C++: 基於OpenSSL的AES256加解密測試
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)四種常用的分組密碼加
2.非對稱加密算法
OpenSSL一共實現了4種非對稱加密算法,包括DH算法、RSA算法、DSA算法和橢圓曲線算法(EC)。DH算法一般用戶密鑰交換。RSA算法既可以用於密鑰交換,也可以用於數字簽名,當然,如果你能夠忍受其緩慢的速度,那麽也可以用於數據加密。DSA算法則一般只用於數字簽名。
3.信息摘要算法
OpenSSL實現了5種信息摘要算法,分別是MD2、MD5、MDC2、SHA(SHA1)和RIPEMD。SHA算法事實上包括了SHA和SHA1兩種信息摘要算法,此外,
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加解密測試