南京郵電大學網路資訊安全——OpenSSL加密資料實驗(實驗二)
- OpenSSL的下載和編譯
- OpenSSL的下載
- OpenSSL的編譯
- 解壓
- 配置
- 編譯
- 利用OpenSSL編程
- 編譯測驗檔案
- 測驗檔案是否通過
- 設定環境變數(如果按照實驗指南來進行安裝,不需要設定環境變數)
- 加密測驗
- 原始碼撰寫
- 編譯和測驗
- 利用Openssl進行加密
- 實驗內容一:利用AES進行加密
- Base64編碼部分
- 不同的加密方式
- 實驗內容二:修改密文測驗
- 實驗內容三:RSA公鑰和私鑰的生產
- 實驗內容四:數字簽名
- 總結
OpenSSL的下載和編譯
OpenSSL的下載
OpenSSL的下載鏈接為http://www.openssl.org/source/,在這里找到對應的下載方式
需要注意的是這里可能要搭個梯子,不然下載的可能會相當慢,當然也可以在國內找鏡像也不是不可以,
需要注意的是下載的時候要找對版本,i386對應IA32架構(32位系統),amd64對應x86-64架構(64位系統)
這里說一點題外話就是amd64即x86-64架構(俗稱的64位架構),由于該架構由amd提出并有inter發揚光大,所以有兩個稱呼,
OpenSSL的編譯
解壓
直接將下載好的內容放入Ubuntu即可,
然后執行一下解壓命令
user1@ubuntu:~/Desktop$ tar -xzvf openssl-3.0.0-alpha6.tar.gz
這里的xzvf引數的含義如下:
- x:解壓tar格式的檔案
- v:解壓時顯示詳細資訊
- z:使用gzip程式解壓
- f:使用歸檔
配置
解壓完成后檢查檔案夾
在檔案夾內運行
user1@ubuntu:~/Desktop/openssl-3.0.0-alpha6$ ./Configure
這里和原本的實驗要輸入的指令不太一樣,原來的指令為:
./config –prefix=/usr/local
這里說一下,-perfix引數的意思是將軟體的安裝路徑指定一下,我這里選擇尊重Ubuntu的規范,不去修改他,同時寫一下安裝路徑的默認規劃為
| 檔案型別 | 路徑 |
|---|---|
| 二進制檔案 | usr\local\bin |
| 組態檔 | usr\local\etc |
| 庫檔案 | usr\local\local |
編譯
在原來的檔案夾里面運行make指令
user1@ubuntu: make & make install
這時螢屏上會出現大量的輸出
等待輸出完成,輸入指令
user1@ubuntu: make test
可以看到正在進行測驗,
需要注意的是在進行測驗的程序中可能會出現某些錯誤,但是秉著夠用就好的原則,我們這里不去關注他,因為這些功能我們可能是用不到的,并且最后的測驗結果也是通過的,
然后執行命令,這個命令記得執行,不然找不到對應的頭檔案和動態庫…這個地方我debug了好久
make install
利用OpenSSL編程
編譯測驗檔案
測驗檔案原始碼如下
#include <stdio.h>
#include <evp.h>
int main()
{
printf("hello world!");
OpenSSL_add_all_algorithms();
return 0;
}
編譯
user1@ubuntu:~/Desktop/OpenSSL_Test$ gcc test.c -I /usr/local/include/openssl/ -lcrypto
其中引數含義如下:
- -I:頭檔案路徑
- -lxxx:在鏈接階段鏈接動態庫libxxx.so,如這里鏈接libcrypto.so檔案
這里說一下如果直接按照實驗指南里面的指令(不完全一致,修改了環境變數)
gcc test.c –o test –I /usr/local/openssl/include /usr/local/libcrypto.a –ldl
會發現在鏈接階段無法通過

測驗檔案是否通過
編譯完成后會出現以下的檔案
直接運行,會出現找不到動態庫的錯誤
原因在于Ubuntu的默認動態庫搜索路徑為/usr/lib,而我自定義的路徑為/usr/local/lib里面,所以需要設定以下環境變數,
設定環境變數(如果按照實驗指南來進行安裝,不需要設定環境變數)
打開元件組態檔
user1@ubuntu:~/Desktop/OpenSSL_Test$ sudo gedit /etc/ld.so.conf
添加自己的動態庫路徑
保存,并更新動態庫快取
sudo ldconfig
再次運行,即可成功

加密測驗
原始碼撰寫
如果直接使用實驗指南里面的原始碼的話會出現以下報錯
經過查詢發現在Openssl更新到1.1版本后,其API有一點點改變,修改后的原始碼如下
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
void tEVP_Encrypt()
{
unsigned char key[EVP_MAX_KEY_LENGTH];//密鑰
unsigned char iv[EVP_MAX_KEY_LENGTH];//初始化向量
/* old usage*/
//EVP_CIPHER_CTX ctx;//EVP演算法背景關系
/* old usage*/
/*new usage*/
//EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
/*new usage*/
unsigned char out[1024];//輸出密文緩沖區
int outl;//密文長度
int outltmp;
char *msg="Hello OpenSSL";//待加密的資料
int rv;
int i;
//設定key和iv(可以采用亂數和可以是用戶輸入)
for(i=0;i<24;i++)
{
key[i]=i;
}
for(i=0;i<8;i++)
{iv[i]=i;
}//初始化密碼演算法結構體
EVP_CIPHER_CTX_init(ctx);
//設定演算法和密鑰以及向量
rv = EVP_EncryptInit_ex(ctx,EVP_des_ede3_cbc(),NULL,key,iv);
if(rv!=1)
{
printf("Err\n");
return;
}
//資料加密
rv = EVP_EncryptUpdate(ctx,out,&outl,(const unsigned char*)msg,strlen(msg));
if(rv!=1)
{
printf("Err\n");
return;
}//結束資料加密,把剩余資料輸出
rv = EVP_EncryptFinal_ex(ctx,out+outl,&outltmp);
if(rv!=1)
{
printf("Err\n");
return;
}
outl = outl +outltmp;
printf("Original text:%s\n",msg);
//列印輸出密文
printf("Length of ciphertext:%d\n Data of ciphertext:\n",outl);
for(i=0;i<outl;i++)
{
printf("0x%02x ",out[i]);
}printf("\n");
}
int main()
{
OpenSSL_add_all_algorithms();
tEVP_Encrypt();
return 0;
}
編譯和測驗
/usr/bin/g++ -g /home/user1/Desktop/OpenSSL_Test/test2.cpp -o /home/user1/Desktop/OpenSSL_Test/test2 -I /usr/local/include/openssl/ -lcrypto
執行即可成功

利用Openssl進行加密
Openssl除了有編程介面外,還提供了命令列介面以便客戶使用
實驗內容一:利用AES進行加密
該實驗有兩個部分:
- 使用Base64和不使用Base64分別進行加密并觀察結果
- 采用不同模式進行加密
Base64編碼部分
首先說明一下Base64的作用,Base64基本上只做了一件事:將二進制資料編碼成了ASCII碼,以便于電子郵電閱讀,知道這點就夠了,
使用以下命令進行Base64加密
openssl enc -aes-256-cbc -salt -in lincoln.txt -out WithoutBase64.encn
其引數含義如下:
- enc:加密
- aes-256-cbc:采用aes演算法進行加密,256位密鑰,CBC模式
- salt:加鹽
- in:輸入檔案
- out:輸出檔案
對于加密完成的檔案,可以看到是一個二進制檔案,無法直接打開,
利用二進制編輯軟體打開,可以看到,其是一堆二進制亂碼
也就是無法直接通過電子郵件,qq聊天框直接傳遞的,
利用以下指令執行Base64編碼
openssl enc -aes-256-cbc -salt -a -in lincoln.txt -out WithBase64.encn
其中-a表示將密文用base64進行編碼,加密結果如下,可以看到,這次就是可讀文本了

不同的加密方式
為了方便起見,我這里都對密文采用了Base64編碼,
首先采用CBC分組鏈接模式加密:
openssl enc -aes-256-cbc -salt -a -in lincoln.txt -out WithBase64CBC.encn
加密密文如下

EBC密碼本加密模式進行加密
openssl enc -aes-256-ebc -salt -a -in lincoln.txt -out WithBase64EBC.encn
密文如下:

實驗內容二:修改密文測驗
我修改了密文檔案,無論是修改還是增刪都會出現報錯
應該是OpenSSL的差錯控制的報錯吧,但也可能是我做的不太對…
實驗內容三:RSA公鑰和私鑰的生產
OpenSSL的公私鑰的生產分兩個步驟:
- 生成私鑰
openssl genrsa -out private.key
- 利用私鑰生成公鑰
openssl rsa -pubout -in private.txt -out public.txt
生成的私鑰如下:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC49ZkZxQwo3ewJ
RHNco+9hfAeoxEZfoG4wGtznGInMYqGdivzhjCK3tBDWdl8bwiJUp6JqoRIeySwb
0xuG4KQMQ5uOtigrCPZ+Wcj5fs/Gve9tMLrT0xVtXltIdRCFuiXKPMJ9ava3oy7Q
cpEIBAhUneN/O+PLirZMmKODx9x46lKCab6T19VQM7f+dWi2aHsFqmQkccaaPSE3
nquRpF6bSggJh2US/v88tCUs7Z+VKpsoCEVumFXF28Nuq8VnLJddfO7KitRS4XWs
VdVNjwjWr2FRL/YzIayYDbJ614azr0uEyoEbT/NtW2AKYJMnqvNbybc55JSDOcLv
k6RVZ1HtAgMBAAECggEAOIjZg0b3sIYk37BMksSJJwMCVFOqLxCanZmYbArUE+US
AVW6djafZgdkHimQaKuuUrHqsy0InOBg2yBsCY4glp8TrUuAe6cBsR1AkQJyAA2O
YZHDiXu70PJGdJ9TrYx4gJiR2kQXpYn7hTt/mTOiWDrqjrl/p3d+wWrmkCFHAq4X
qpMuiBYIJNcKQa+LgUq71rHchjsNeDmKRdjId+4zBYWygcxoRL/p4cfhs7sWpk5n
5beGanFYhauTRxQzrsfsePQP3PLQSJljkXVhIFC0mASORR0WnYw3j3n6599scmRN
w6lpAU7JnTtXk3vS8CA7kXABCYAuhYHq9jSlOMgfAQKBgQDp8a0PRnj/qGiGDELk
e+PzbKArOHfCnGQJD+N0Kwd0t0jByJ4TY1poBwKSGP95o2byYQfSnssckiPkVeiH
VMY7EuYD5PzoTGdkUpIBfyOhlqABAd99x2AUPgR7/a689rZb+ewV6s+dw0/avSqs
K/c2uqGu97wx+hyAh0EnurtiMwKBgQDKZai8Cj66uwZMntoEA29NGa7IJ2Gi0zpk
OhhF6MblI+TABgl/RM21Cob/6dmRerJNU0cKgWOtdRjhuJCZozkHOC4dY3m268WR
NkbchqBMjqpJSQj1oHlZ1opOl9AyM1pDRkdbGoXrl/zxEuRwpStokeCjvaTObK/c
RZEdJfObXwKBgGTL0UHMnmOg3vAqpkOlsZB3VAdrPAZotZ1F8D1kMME0GzALTTiT
TSeXJZ9nD+QL6FY0QleYPXEg8j/2V8q/Vu2q9dnltqYsDTwna2sjqWl86ZGlifK6
jYYLNolpwvj935J/ex3yXuPdfDGF4bXu94PoI7OsX7S0y8UBAaypgwULAoGAGdog
UlxwpMNMy66ipE6YAd4c8B3vn6+hTroI7a0M8qnCBzD+N45fRBejJL8G9kkYyz2u
3k2moLpLQlGjzqwFlcF8Sm6xVkcJRkILjRF5Gi5C2/eDOHSV6362zdEgW7kpd1xb
suxRXMVeHqDOIwFF6SZw7hlEGsXRNK6CGZoGYrsCgYEAmQXSYcSU2WCF28fxFzNX
IB8G56o3iCPMUsdxkWeIVPRURjpY5QJ8G4r6LDZyltyRIcNEF3Ak/NiJL//LWbPQ
44KxH2KeIcOcTF6Nr65u8YFLHtUj4AUSgdjN4+jicxk2cOhwXzogpOKf4tRePYrc
mwi8n7PJhj2bgzoaxwULXnQ=
-----END PRIVATE KEY-----
公鑰如下:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuPWZGcUMKN3sCURzXKPv
YXwHqMRGX6BuMBrc5xiJzGKhnYr84Ywit7QQ1nZfG8IiVKeiaqESHsksG9MbhuCk
DEObjrYoKwj2flnI+X7Pxr3vbTC609MVbV5bSHUQhbolyjzCfWr2t6Mu0HKRCAQI
VJ3jfzvjy4q2TJijg8fceOpSgmm+k9fVUDO3/nVotmh7BapkJHHGmj0hN56rkaRe
m0oICYdlEv7/PLQlLO2flSqbKAhFbphVxdvDbqvFZyyXXXzuyorUUuF1rFXVTY8I
1q9hUS/2MyGsmA2yeteGs69LhMqBG0/zbVtgCmCTJ6rzW8m3OeSUgznC75OkVWdR
7QIDAQAB
-----END PUBLIC KEY-----
在RSA演算法里面,鑰匙長度越長,消耗資源越多,對于一個數字簽名來說,私鑰只需要用一次,而公鑰需要使用多次,所以從總體角度來說,私鑰要比公鑰長的多,
實驗內容四:數字簽名
使用以下指令進行數字簽名
回顧以下數字簽名的程序:首先進行Hash處理,后對Hash值進行簽名
openssl dgst -sha1 -sign private.txt -out mytest.dig mytest
引數:
- dgst:digest,數字簽名
- sha1:采用sha1進行hash
- sign:簽名鑰匙
需要指出的是簽名為二進制序列,所以無法正常打開,并且Openssl在簽名工具里面也沒有提供Base64轉碼工具,以下是我的數字簽名

驗證簽名采用如下指令
openssl dgst -sha1 -verify pubkey.pem -signature B13040450.sha1 B13040450
驗證成功:

總結
總體來說,這次的實驗雖然涉及到了Ubuntu下的編譯和編程,但是可能由于openssl用的人比較多,編譯程序中并沒有“煉丹“,并且測驗原始碼都已經給出了,所以總體來說比較簡單,相較第一個實驗來說,因為并沒有涉及到軟體的使用,所以并沒有像使用WireShark時由于每個人的WireShark版本不一致導致實驗難易不一,
需要注意的有兩個點:
- 動態庫名稱及路徑的設定,在這個實驗里面要鏈接的動態庫為libcrypto.so
- Openssl的API的變化
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/100735.html
標籤:其他
