1. 程式人生 > >C++: 基於OpenSSL的AES256加解密測試

C++: 基於OpenSSL的AES256加解密測試

技術分享 以及 ora 實習 erl this ifs 測試結果 binary

2018-07-12

暑假要求專業實習,要有周記和工作總結。之前老早就有過寫博客的想法,因為可以讓自己的學習生涯有跡可循。不過租的服務器即將到期,就不自己建站了。希望通過博客園這個平臺記錄下自己的成長吧。希望自己能堅持下去,也希望能留下一些對別人有用的東西。

第一篇內容是關於使用OpenSSL庫對字符串和文件進行AES256加解密:

環境: 操作系統:windows 10

開發工具:Visual Studio 2015

關於OpenSSL 安裝配置參考以下博客,傳送門:https://www.jb51.net/article/119025.htm

OpenSSL簡介

OpenSSL是一個基於密碼學的安全開發包,OpenSSL提供的功能相當強大和全面,囊括了主要的密碼算法、常用的密鑰和證書封裝管理功能以及SSL協議,並提供了豐富的應用程序供測試或其它目的使用。具體包含以下功能:

1.對稱加密算法

OpenSSL一共提供了8種對稱加密算法,其中7種是分組加密算法,僅有的一種流加密算法是RC4。這7種分組加密算法分別是AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都支持電子密碼本模式(ECB)、加密分組鏈接模式(CBC)、加密反饋模式(CFB)和輸出反饋模式(OFB)四種常用的分組密碼加

密模式。其中,AES使用的加密反饋模式(CFB)和輸出反饋模式(OFB)分組長度是128位,其它算法使用的則是64位。事實上,DES算法裏面不僅僅是常用的DES算法,支持三個密鑰和兩個密鑰3DES算法。

2.非對稱加密算法

OpenSSL一共實現了4種非對稱加密算法,包括DH算法、RSA算法、DSA算法和橢圓曲線算法(EC)。DH算法一般用戶密鑰交換。RSA算法既可以用於密鑰交換,也可以用於數字簽名,當然,如果你能夠忍受其緩慢的速度,那麽也可以用於數據加密。DSA算法則一般只用於數字簽名。

3.信息摘要算法

OpenSSL實現了5種信息摘要算法,分別是MD2、MD5、MDC2、SHA(SHA1)和RIPEMD。SHA算法事實上包括了SHA和SHA1兩種信息摘要算法,此外,

OpenSSL還實現了DSS標準中規定的兩種信息摘要算法DSS和DSS1。

4.密鑰和證書管理

密鑰和證書管理是PKI的一個重要組成部分,OpenSSL為之提供了豐富的功能,支持多種標準。 首先,OpenSSL實現了ASN.1的證書和密鑰相關標準,提供了對證書、公鑰、私鑰、證書請求以及CRL等數據對象的DER、PEM和BASE64的編解碼功能。OpenSSL提供了產生各種公開密鑰對和對稱密鑰的方法、函數和應用程序,同時提供了對公鑰和私鑰的DER編解碼功能。並實現了私鑰的PKCS#12和PKCS#8的編解碼功能。OpenSSL在標準中提供了對私鑰的加密保護功能,使得密鑰可以安全地進行存儲和分發。 在此基礎上,OpenSSL實現了對證書的X.509標準編解碼、PKCS#12格式的編解碼以及PKCS#7的編解碼功能。並提供了一種文本數據庫,支持證書的管理功能,包括證書密鑰產生、請求產生、證書簽發、吊銷和驗證等功能。 事實上,OpenSSL提供的CA應用程序就是一個小型的證書管理中心(CA),實現了證書簽發的整個流程和證書管理的大部分機制。

5.SSL和TLS協議

SSL(Secure Sockets Layer 安全套接層)是一種基於Web應用的安全通信協議,最早由Netscape(網景)公司提出。SSL介於TCP協議和應用層 協議之間,主要作用就是將HTTP、FTP等應用層的數據進行加密然後依托可靠的TCP協議在互聯網上傳輸到目的地,其中最典型的應用就是https。

代碼展示

  1 #include <openssl/aes.h>
  2 #include <time.h>
  3 #include "iostream"
  4 using namespace std;
  5 #include "string"
  6 #include "fstream"
  7 #pragma comment(lib,"ws2_32.lib")
  8 #pragma comment(lib,"libssl.lib")
  9 #pragma comment(lib,"libcrypto.lib")
 10 
 11 #define RELESE(P) if (P)         12 {                                 13     delete P;                     14     P = NULL;                     15 }
 16 
 17 #define RELESE_ARRAY(P) if (P)   18 {                                 19     delete[] P;                     20     P = NULL;                     21 }
 22 
 23 
 24 // 測試使用aes加密算法的例子(字符串)
 25 /*
 26 int main()
 27 {
 28     unsigned char buf[16];
 29     memset(buf, 1, sizeof(buf));
 30     strcpy((char *)buf, "this is mingwen");
 31 
 32     cout << "current buf value is :" << buf << endl;
 33 
 34     unsigned char buf2[16];
 35     unsigned char buf3[16];
 36     unsigned char aes_keybuf[32];
 37 
 38     memset(aes_keybuf, 0, sizeof(aes_keybuf));
 39     strcpy((char *)aes_keybuf, "key1");
 40     cout << "current aes_keybuf value is :" << aes_keybuf << endl;
 41     AES_KEY aeskey;
 42 
 43     AES_set_encrypt_key(aes_keybuf, 256, &aeskey);
 44     //cout << "AESkey is:" << aeskey << endl;
 45 
 46     AES_encrypt(buf, buf2, &aeskey);
 47     cout << "current buf2 value is :" << buf2 << endl;
 48 
 49     memset(aes_keybuf, 0, sizeof(aes_keybuf));
 50     strcpy((char *)aes_keybuf, "key2");
 51     cout << "current aes_keybuf value is :" << aes_keybuf << endl;
 52     
 53     AES_set_decrypt_key(aes_keybuf, 256, &aeskey);
 54 
 55     AES_decrypt(buf2, buf3, &aeskey);
 56     cout << "current buf2 value is :" << buf2 << endl;
 57     cout << "*********************************" << endl;
 58     cout << "current buf3 value is :" << buf3 << endl;
 59 
 60     if (memcmp(buf, buf3, sizeof(buf)) != 0)
 61         printf("AES256 test success\r\n");
 62     else
 63         printf("AES256 test fail\r\n");
 64     return 0;
 65 }
 66 */
 67 
 68 
 69 
 70 
 71 // AES文件加密函數 ///////////////////////////////////////////////////////////
 72 int TestAesEncryptFile(std::string in_file_path, std::string out_file_path, char Key[32])
 73 {
 74     int encrypt_chunk_size = 16;
 75 
 76     ifstream fin(in_file_path.c_str(), ios::binary);
 77     ofstream fout(out_file_path, ios::binary);
 78 
 79     if (!fin)
 80     {
 81         cout << "Can not open fin file." << endl;
 82         return 1;
 83     }
 84     if (!fout)
 85     {
 86         cout << "Can not open fout file." << endl;
 87         return 1;
 88     }
 89 
 90     //用指定密鑰對一段內存進行加密,結果放在outbuffer中
 91     unsigned char aes_keybuf[32];
 92     memset(aes_keybuf, 0, sizeof(aes_keybuf));
 93     strcpy((char *)aes_keybuf, Key);
 94     AES_KEY aeskey;
 95     AES_set_encrypt_key(aes_keybuf, 256, &aeskey);
 96 
 97     char *in_data = new char[encrypt_chunk_size + 1];
 98     char *out_data = new char[encrypt_chunk_size + 1];
 99     while (!fin.eof())
100     {
101         fin.read(in_data, encrypt_chunk_size);
102         if (fin.gcount() < encrypt_chunk_size)
103         {
104             fout.write(in_data, fin.gcount());
105         }
106         else
107         {
108             AES_encrypt((const unsigned char *)in_data, (unsigned char *)out_data, &aeskey);
109             fout.write(out_data, fin.gcount());
110         }
111     };
112 
113     fout.close();
114     fin.close();
115 
116     RELESE_ARRAY(in_data);
117     RELESE_ARRAY(out_data);
118 
119     return 0;
120 }
121 
122 // AES文件解密函數 //////////////////////////////////////////////////////////
123 int TestAesDecryptFile(std::string in_file_path, std::string out_file_path, char Key[32])
124 {
125     int encrypt_chunk_size = 16;
126     ifstream fin(in_file_path.c_str(), ios::binary);
127     ofstream fout(out_file_path, ios::binary);
128 
129     if (!fin)
130     {
131         cout << "Can not open fin file." << endl;
132         return 1;
133     }
134     if (!fout)
135     {
136         cout << "Can not open fout file." << endl;
137         return 1;
138     }
139 
140     //用指定密鑰對一段內存進行加密,結果放在outbuffer中
141     unsigned char aes_keybuf[32];
142     memset(aes_keybuf, 0, sizeof(aes_keybuf));
143     strcpy((char *)aes_keybuf, Key);
144     AES_KEY aeskey;
145     AES_set_decrypt_key(aes_keybuf, 256, &aeskey);
146 
147     char *in_data = new char[encrypt_chunk_size + 1];
148     char *out_data = new char[encrypt_chunk_size + 1];
149     int i = 0;
150     while (!fin.eof())
151     {
152         fin.read(in_data, encrypt_chunk_size);
153         if (fin.gcount() < encrypt_chunk_size)
154         {
155             fout.write(in_data, fin.gcount());
156         }
157         else
158         {
159             AES_decrypt((unsigned char *)in_data, (unsigned char *)out_data, &aeskey);
160             fout.write(out_data, fin.gcount());
161         }
162     };
163 
164     fout.close();
165     fin.close();
166 
167     RELESE_ARRAY(in_data);
168     RELESE_ARRAY(out_data);
169 
170     return 0;
171 }
172 
173 int main()
174 {
175     time_t t1, t2, t3, t4;
176     t1 = time(NULL);
177     printf("加解密起始時間: %s\n", ctime(&t1));
178     TestAesEncryptFile("D://model.bin", "D://model.bin.enc", "xxyy1234567890");
179     t2 = time(NULL);
180     printf("AES256加密成功!\n");
181     printf("加密用時: %lld秒\n", (t2 - t1));
182     t3 = time(NULL);
183     TestAesDecryptFile("D://model.bin.enc", "D://modelnew.bin", "xxyy1234567890");
184     t4 = time(NULL);
185     printf("AES256解密成功!\n");
186     printf("解密用時: %lld秒\n", (t4 - t3));
187 
188     return 0;
189 }

測試結果

測試文件:model.bin (920MB)

技術分享圖片

技術分享圖片

windows命令行進入工作目錄,執行 fc model.bin modelnew.bin >> 1.txt 比較model.bin和modelnew.bin異同:

技術分享圖片

-----------------------------------------------

至此,AES256加解密測試順利結束。

C++: 基於OpenSSL的AES256加解密測試