OpenSSL使用AES實(shí)現(xiàn)文件加解密功能
前言
AES(Advanced Encryption Standard)是一種對(duì)稱加密算法,它是目前廣泛使用的加密算法之一。AES算法是由美國(guó)國(guó)家標(biāo)準(zhǔn)與技術(shù)研究院(NIST)于2001年發(fā)布的,它取代了原先的DES(Data Encryption Standard)算法,成為新的標(biāo)準(zhǔn)。AES是一種對(duì)稱加密算法,意味著加密和解密使用相同的密鑰。這就要求密鑰的安全性非常重要,因?yàn)槿魏螕碛忻荑€的人都能進(jìn)行加密和解密操作。其密鑰長(zhǎng)度,包括128位、192位和256位。不同長(zhǎng)度的密鑰提供了不同級(jí)別的安全性,通常更長(zhǎng)的密鑰長(zhǎng)度意味著更高的安全性。
該算法支持多種工作模式,其中兩種常見的模式是CBC(Cipher Block Chaining)和ECB(Electronic Codebook)。
- CBC 模式(Cipher Block Chaining):
- 工作原理:
- CBC模式對(duì)每個(gè)明文塊進(jìn)行加密前,先與前一個(gè)密文塊進(jìn)行異或操作。首個(gè)塊使用一個(gè)初始化向量(IV)與明文異或。這種鏈?zhǔn)椒答仚C(jī)制使得每個(gè)密文塊的加密都依賴于前一個(gè)塊的密文,從而增加了安全性。
- 特點(diǎn):
- 帶有初始化向量,對(duì)同樣的明文塊加密得到的密文塊會(huì)隨著其前面的明文塊的不同而不同。
- 適用于加密長(zhǎng)度超過一個(gè)塊的數(shù)據(jù)。
- 優(yōu)點(diǎn)和缺點(diǎn):
- 優(yōu)點(diǎn):提供更高的安全性,適用于加密大塊的數(shù)據(jù)。
- 缺點(diǎn):由于加密是依賴于前一個(gè)塊的密文,所以無法進(jìn)行并行加密處理。
- 工作原理:
- ECB 模式(Electronic Codebook):
- 工作原理:
- ECB模式將明文分割成塊,每個(gè)塊獨(dú)立加密,然后再組合成密文。相同的明文塊將始終加密為相同的密文塊。
- 特點(diǎn):
- 不需要初始化向量,同樣的明文會(huì)得到同樣的密文。
- 適用于加密獨(dú)立的數(shù)據(jù)塊,但對(duì)于相同的塊,ECB模式下的輸出相同。
- 優(yōu)點(diǎn)和缺點(diǎn):
- 優(yōu)點(diǎn):簡(jiǎn)單,易于實(shí)現(xiàn)。
- 缺點(diǎn):相同的明文塊生成相同的密文塊,可能導(dǎo)致安全性問題。不適用于加密大塊的數(shù)據(jù)。
- 工作原理:
在選擇模式時(shí),需要根據(jù)具體的應(yīng)用場(chǎng)景和需求權(quán)衡安全性和性能。一般來說,CBC模式是更安全的選擇,而ECB模式可能更容易實(shí)現(xiàn)和理解。在實(shí)際應(yīng)用中,還可以考慮其他模式,如CTR(Counter)模式和GCM(Galois/Counter Mode)模式等,這些模式結(jié)合了安全性和性能的考慮。
本次案例中所需要使用的頭文件信息如下所示;
#define _CRT_SECURE_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <iostream> #include <openssl/err.h> #include <openssl/aes.h> #include <openssl/evp.h> #include <openssl/crypto.h> #include <openssl/pem.h> extern "C" { #include <openssl/applink.c> } #pragma comment(lib,"libssl_static.lib") #pragma comment(lib,"libcrypto.lib")
使用CBC模式加解密
Cipher Block Chaining (CBC) 模式是一種對(duì)稱加密的分組密碼工作模式。在 CBC 模式中,明文被分成固定大小的塊,并使用加密算法逐個(gè)處理這些塊。每個(gè)塊都與前一個(gè)塊的密文進(jìn)行異或運(yùn)算,然后再進(jìn)行加密。這個(gè)過程導(dǎo)致了一種“鏈接”效果,因此得名 Cipher Block Chaining。
以下是 CBC 模式的詳細(xì)概述:
初始向量 (Initialization Vector, IV):
- 在 CBC 模式中,每個(gè)消息的第一個(gè)塊使用一個(gè)初始向量 (IV)。IV 是一個(gè)固定長(zhǎng)度的隨機(jī)數(shù),它在每次加密不同消息時(shí)都應(yīng)該是唯一的。IV 的作用是在每個(gè)塊的加密中引入隨機(jī)性,以防止相同的明文塊生成相同的密文塊。
分組加密:
- 消息被分成固定大小的塊(通常為 64 比特或 128 比特),然后每個(gè)塊都被分組加密。最常用的塊加密算法是 AES。
異或運(yùn)算:
- 在每個(gè)塊加密之前,明文塊與前一個(gè)密文塊進(jìn)行異或運(yùn)算。這就是“鏈接”發(fā)生的地方。第一個(gè)塊與 IV 異或。
加密:
- 異或運(yùn)算后的結(jié)果被送入塊加密算法進(jìn)行加密。得到的密文塊成為下一個(gè)塊的 IV。
解密:
- 在解密時(shí),密文塊被送入塊解密算法進(jìn)行解密。解密后的結(jié)果與前一個(gè)密文塊進(jìn)行異或運(yùn)算,得到明文塊。
模式串行化:
- CBC 模式是串行的,因?yàn)槊總€(gè)塊的加密都依賴于前一個(gè)塊的密文。這也意味著無法并行處理整個(gè)消息。
填充:
- 如果明文的長(zhǎng)度不是塊大小的整數(shù)倍,需要進(jìn)行填充。常見的填充方案有 PKCS#7 填充。
安全性:
- 當(dāng)使用 CBC 模式時(shí),密文塊的順序?qū)Π踩灾陵P(guān)重要。如果消息的兩個(gè)塊對(duì)調(diào),解密后會(huì)得到不同的明文。因此,必須保證密文塊的順序不被篡改。
使用場(chǎng)景:
- CBC 模式常用于保護(hù)傳輸層安全協(xié)議(如 TLS)中,以提供加密和數(shù)據(jù)完整性。
總體而言,CBC 模式提供了一種相對(duì)強(qiáng)大的加密方法,但在實(shí)現(xiàn)時(shí)需要注意使用隨機(jī)且不可預(yù)測(cè)的 IV 以及處理填充的問題。
AES_set_encrypt_key
函數(shù)。具體來說,它用于將原始密鑰設(shè)置為可以在 AES 加密算法中使用的格式。以下是該函數(shù)的原型:
int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
userKey
:指向用于設(shè)置密鑰的輸入數(shù)據(jù)的指針,即原始密鑰。bits
:密鑰長(zhǎng)度,以比特為單位。在使用 AES 加密算法時(shí),通常為 128、192 或 256。key
:指向AES_KEY
結(jié)構(gòu)的指針,用于存儲(chǔ)設(shè)置后的密鑰信息。
該函數(shù)返回值為零表示成功,非零表示失敗。成功調(diào)用后,key 參數(shù)中存儲(chǔ)了經(jīng)過格式化的密鑰信息,可以在后續(xù)的 AES 加密操作中使用。
AES_cbc_encrypt 是 OpenSSL 庫中用于執(zhí)行 AES 算法中的 Cipher Block Chaining (CBC) 模式的函數(shù)。在 CBC 模式中,每個(gè)明文塊在加密之前會(huì)與前一個(gè)密文塊進(jìn)行異或運(yùn)算,以增加密碼的隨機(jī)性。
以下是 AES_cbc_encrypt
函數(shù)的原型:
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc);
in
:指向輸入數(shù)據(jù)(明文)的指針。out
:指向輸出數(shù)據(jù)(密文)的指針。length
:數(shù)據(jù)的長(zhǎng)度,以字節(jié)為單位。key
:指向AES_KEY
結(jié)構(gòu)的指針,其中包含了加密密鑰。ivec
:Initialization Vector(IV),用于增強(qiáng)密碼的隨機(jī)性,也是前一個(gè)密文塊。在 CBC 模式中,IV 對(duì)于第一個(gè)數(shù)據(jù)塊是必需的,之后的 IV 由前一個(gè)密文塊決定。enc
:指定操作是加密(AES_ENCRYPT
)還是解密(AES_DECRYPT
)。
AES_set_decrypt_key
函數(shù)。該函數(shù)用于將加密時(shí)使用的密鑰調(diào)整為解密時(shí)使用的密鑰,以便進(jìn)行解密操作。
以下是 AES_set_decrypt_key
函數(shù)的原型:
int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
userKey
:指向用于設(shè)置解密密鑰的輸入密鑰數(shù)據(jù)的指針。bits
:密鑰長(zhǎng)度,以比特為單位。支持的長(zhǎng)度包括 128、192 和 256 比特。key
:指向AES_KEY
結(jié)構(gòu)的指針,該結(jié)構(gòu)將存儲(chǔ)設(shè)置后的解密密鑰。
實(shí)現(xiàn)加解密功能,如下openssl_aes_cbc_encrypt
用于使用CBC模式加密數(shù)據(jù),openssl_aes_cbc_decrypt
則相反用于解密數(shù)據(jù)。
// 初始化密鑰 const unsigned char key[AES_BLOCK_SIZE] = { 0x12,0x55,0x64,0x69,0xf1 }; // 初始化向量 unsigned char iv[AES_BLOCK_SIZE] = { 0 }; // AES CBC 模式加密 // 參數(shù): // - in: 待加密的數(shù)據(jù) // - len: 待加密數(shù)據(jù)的長(zhǎng)度 // - out: 存放加密結(jié)果的緩沖區(qū) // 返回值: // - 返回填充后加密數(shù)據(jù)的長(zhǎng)度,失敗返回-1 int openssl_aes_cbc_encrypt(char* in, size_t len, char* out) { AES_KEY aes; // 填充數(shù)據(jù)為AES_BLOCK_SIZE的整數(shù)倍 char* aesIn; int blockNum, aesInLen; // 設(shè)置加密密鑰 if (AES_set_encrypt_key(key, 128, &aes) < 0) { return -1; } // 判斷原始數(shù)據(jù)長(zhǎng)度是否AES_BLOCK_SIZE的整數(shù)倍 if ((len % AES_BLOCK_SIZE) != 0) { // 不是整數(shù)倍則用0填充 blockNum = len / AES_BLOCK_SIZE + 1; aesInLen = blockNum * AES_BLOCK_SIZE; aesIn = (char*)calloc(aesInLen, 1); memcpy(aesIn, in, len); } else { aesInLen = len; aesIn = (char*)calloc(aesInLen, 1); memcpy(aesIn, in, len); } // AES CBC 模式加密 AES_cbc_encrypt((unsigned char*)aesIn, (unsigned char*)out, aesInLen, &aes, iv, AES_ENCRYPT); // 釋放分配的內(nèi)存 free(aesIn); // 返回填充后加密數(shù)據(jù)的長(zhǎng)度 return aesInLen; } // AES CBC 模式解密 // 參數(shù): // - in: 待解密的數(shù)據(jù) // - len: 待解密數(shù)據(jù)的長(zhǎng)度 // - out: 存放解密結(jié)果的緩沖區(qū) // 返回值: // - 成功返回0,失敗返回-1 int openssl_aes_cbc_decrypt(char* in, size_t len, char* out) { AES_KEY aes; // 設(shè)置解密密鑰 if (AES_set_decrypt_key(key, 128, &aes) < 0) { return -1; } // AES CBC 模式解密 AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_DECRYPT); // 返回成功 return 0; }
當(dāng)需要對(duì)數(shù)據(jù)加密時(shí),首先打開被加密文件這里我們打開的時(shí)csdn.zip
文件,加密后會(huì)寫出為csdn.cbc
文件;
int main(int argc, char* argv[]) { // 存放填充字節(jié)數(shù)的數(shù)組 char offset[4] = { '0' }; char* src = nullptr, *dst = nullptr; int inlen, outlen, size; FILE* srcFile, *dstFile; // 打開被加密源文件 srcFile = fopen("d://comp/csdn.zip", "rb"); // 加密后寫出文件 dstFile = fopen("d://comp/csdn.cbc", "wb+"); // 獲取文件大小 fseek(srcFile, 0, SEEK_END); inlen = ftell(srcFile); if (inlen < 0) { return 0; } fseek(srcFile, 0, SEEK_SET); // ------------------------------------------------------- // 開始加密 src = (char*)calloc(inlen, 1); size = fread(src, 1, inlen, srcFile); std::cout << "讀入字節(jié): " << size << std::endl; // 輸出變量申請(qǐng)的空間額外增加16字節(jié) outlen = (inlen / 16 + 1) * 16; dst = (char*)calloc(outlen, 1); // 調(diào)用加密函數(shù) size = openssl_aes_cbc_encrypt(src, inlen, dst); // 獲取填充的字節(jié)數(shù),記錄到輸出文件的前4個(gè)字節(jié)內(nèi) sprintf(offset, "%d", size - inlen); fwrite(offset, sizeof(char), 4, dstFile); // ------------------------------------------------------- // 輸出加密后的文件或者解密后的文件,文件大小應(yīng)與原始文件一致 size = fwrite(dst, 1, size, dstFile); std::cout << "輸出文件大小: " << size << std::endl; fcloseall(); free(src); free(dst); system("pause"); return 0; }
運(yùn)行后輸出效果圖如下所示;
解密時(shí)同樣需要打開文件,將加密文件csdn.cbc
打開,并解密輸出成csdnde.zip
文件;
int main(int argc, char* argv[]) { // 存放填充字節(jié)數(shù)的數(shù)組 char offset[4] = { '0' }; char* src = nullptr, *dst = nullptr; int inlen, outlen, size; FILE* srcFile, *dstFile; // 打開加密后的文件 srcFile = fopen("d://comp/csdn.cbc", "rb"); // 解密后寫出的文件 dstFile = fopen("d://comp/csdnde.zip", "wb+"); // 獲取文件大小 fseek(srcFile, 0, SEEK_END); inlen = ftell(srcFile); if (inlen < 0) { return 0; } fseek(srcFile, 0, SEEK_SET); // ------------------------------------------------------- fread(offset, sizeof(char), 4, srcFile); inlen -= 4; src = (char*)calloc(inlen, 1); // 從加密后的文件中獲取填充的字節(jié)數(shù) size = fread(src, 1, inlen, srcFile); std::cout << "讀入字節(jié): " << size << std::endl; // 得到原始文件的大小 size = size - atoi(offset); outlen = (inlen / 16 + 1) * 16; dst = (char*)calloc(outlen, 1); // 解密 openssl_aes_cbc_decrypt(src, inlen, dst); // ------------------------------------------------------- // 輸出加密后的文件或者解密后的文件,文件大小應(yīng)與原始文件一致 size = fwrite(dst, 1, size, dstFile); std::cout << "輸出文件大小: " << size << std::endl; fcloseall(); free(src); free(dst); system("pause"); return 0; }
運(yùn)行后輸出效果圖如下所示;
使用ECB模式加解密
Electronic Codebook (ECB) 模式是一種對(duì)稱加密的分組密碼工作模式。在 ECB 模式中,每個(gè)明文塊都被獨(dú)立加密,不受其他塊的影響。這意味著相同的明文塊將始終生成相同的密文塊,這可能導(dǎo)致一些安全性問題。
以下是 ECB 模式的詳細(xì)概述:
分組加密:
- 消息被分成固定大小的塊(通常為 64 比特或 128 比特),然后每個(gè)塊都被獨(dú)立加密。最常用的塊加密算法是 AES。
無鏈接:
- 在 ECB 模式中,每個(gè)塊的加密是獨(dú)立的,不會(huì)受到前一個(gè)或后一個(gè)塊的影響。這意味著相同的明文塊將生成相同的密文塊。
模式串行化:
- ECB 模式允許對(duì)整個(gè)消息進(jìn)行并行處理,因?yàn)槊總€(gè)塊都是獨(dú)立加密的。這是與 CBC 模式相比的一個(gè)優(yōu)勢(shì),因?yàn)樗试S更高效的實(shí)現(xiàn)。
填充:
- 如果明文的長(zhǎng)度不是塊大小的整數(shù)倍,需要進(jìn)行填充。常見的填充方案有 PKCS#7 填充。
安全性問題:
- 主要的安全性問題在于相同的明文塊生成相同的密文塊,這可能導(dǎo)致一些攻擊。例如,如果兩個(gè)塊的內(nèi)容相同,那么它們的密文也將相同。
使用場(chǎng)景:
- 由于安全性問題,ECB 模式并不適合所有場(chǎng)景。一般來說,ECB 模式主要用于對(duì)稱加密算法的基本理解和學(xué)術(shù)研究,而在實(shí)際應(yīng)用中更常使用其他工作模式,如 CBC 或 GCM。
總體而言,ECB 模式是一種簡(jiǎn)單的分組密碼工作模式,但由于安全性問題,實(shí)際應(yīng)用中更常使用其他工作模式。
AES_ecb_encrypt
是 OpenSSL 庫中用于執(zhí)行 AES 算法的 ECB 模式加密的函數(shù)。下面是對(duì)該函數(shù)的詳細(xì)概述:
int AES_ecb_encrypt(const unsigned char *input, unsigned char *output, const AES_KEY *key, const int enc);
參數(shù)說明:
input
: 要加密的數(shù)據(jù)的輸入緩沖區(qū)的指針。output
: 加密后的數(shù)據(jù)的輸出緩沖區(qū)的指針。key
: AES 密鑰的結(jié)構(gòu)體指針,其中包含了加密所需的密鑰信息。enc
: 一個(gè)整數(shù)值,用于指定是執(zhí)行加密(AES_ENCRYPT
)還是解密(AES_DECRYPT
)操作。
返回值:
- 返回 0 表示成功,其他值表示錯(cuò)誤。
功能說明:
AES_ecb_encrypt
函數(shù)用于在 ECB 模式下執(zhí)行 AES 算法的加密或解密操作,具體取決于enc
參數(shù)。- 在 ECB 模式下,該函數(shù)將輸入的數(shù)據(jù)塊獨(dú)立地加密(或解密),每個(gè)塊的輸出結(jié)果不受前后塊的影響。
- 函數(shù)通過
key
參數(shù)提供的密鑰信息執(zhí)行加密或解密操作。
AES_ecb_encrypt
是 OpenSSL 庫中用于執(zhí)行 AES 算法的 ECB 模式加密或解密的函數(shù)。下面是對(duì)該函數(shù)的詳細(xì)概述:
int AES_ecb_encrypt(const unsigned char *input, unsigned char *output, const AES_KEY *key, const int enc);
參數(shù)說明:
input
: 要加密或解密的數(shù)據(jù)塊的輸入緩沖區(qū)指針。output
: 加密或解密后的數(shù)據(jù)塊的輸出緩沖區(qū)指針。key
: AES 密鑰的結(jié)構(gòu)體指針,包含了加密或解密所需的密鑰信息。enc
: 一個(gè)整數(shù)值,用于指定是執(zhí)行加密(AES_ENCRYPT
)還是解密(AES_DECRYPT
)操作。
返回值:
- 返回 0 表示成功,其他值表示錯(cuò)誤。
功能說明:
AES_ecb_encrypt
函數(shù)用于在 ECB 模式下執(zhí)行 AES 算法的加密或解密操作,具體取決于enc
參數(shù)。- 在 ECB 模式下,該函數(shù)將輸入的數(shù)據(jù)塊獨(dú)立地加密(或解密),每個(gè)塊的輸出結(jié)果不受前后塊的影響。
- 函數(shù)通過
key
參數(shù)提供的密鑰信息執(zhí)行加密或解密操作。
// AES ECB 模式加密 // 參數(shù): // - in: 待加密的數(shù)據(jù) // - len: 待加密數(shù)據(jù)的長(zhǎng)度 // - out: 存放加密結(jié)果的緩沖區(qū) // 返回值: // - 成功返回填充后加密數(shù)據(jù)的長(zhǎng)度,失敗返回-1 int openssl_aes_ecb_enrypt(char* in, size_t len, char* out) { int i; int blockNum; int aesInLen; char* aesIn; AES_KEY aes; // 設(shè)置加密密鑰 if (AES_set_encrypt_key(key, 128, &aes) < 0) return -1; // 判斷原始數(shù)據(jù)長(zhǎng)度是否AES_BLOCK_SIZE的整數(shù)倍 if ((len % AES_BLOCK_SIZE) != 0) { blockNum = len / AES_BLOCK_SIZE + 1; aesInLen = blockNum * AES_BLOCK_SIZE; aesIn = (char*)calloc(aesInLen, 1); memcpy(aesIn, in, len); } else { blockNum = len / AES_BLOCK_SIZE; aesInLen = len; aesIn = (char*)calloc(aesInLen, 1); memcpy(aesIn, in, len); } // 由于ECB每次只處理AES_BLOCK_SIZE大小的數(shù)據(jù),所以通過循環(huán)完成所有數(shù)據(jù)的加密 for (i = 0; i < blockNum; i++) { AES_ecb_encrypt((unsigned char*)aesIn, (unsigned char*)out, &aes, AES_ENCRYPT); aesIn += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; } // 釋放內(nèi)存 // free(aesIn); // 返回填充后加密數(shù)據(jù)的長(zhǎng)度 return aesInLen; } // AES ECB 模式解密 // 參數(shù): // - in: 待解密的數(shù)據(jù) // - len: 待解密數(shù)據(jù)的長(zhǎng)度 // - out: 存放解密結(jié)果的緩沖區(qū) // 返回值: // - 成功返回0,失敗返回-1 int openssl_aes_ecb_decrypt(char* in, size_t len, char* out) { unsigned int i; AES_KEY aes; // 設(shè)置解密密鑰 if (AES_set_decrypt_key(key, 128, &aes) < 0) { return -1; } // 循環(huán)解密每個(gè)數(shù)據(jù)塊 for (i = 0; i < len / AES_BLOCK_SIZE; i++) { AES_ecb_encrypt((unsigned char*)in, (unsigned char*)out, &aes, AES_DECRYPT); in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; } // 返回成功 return 0; }
當(dāng)需要對(duì)數(shù)據(jù)加密時(shí),首先打開被加密文件這里我們打開的時(shí)csdn.zip
文件,加密后會(huì)寫出為csdn.ecb
文件;
int main(int argc, char* argv[]) { // 存放填充字節(jié)數(shù)的數(shù)組 char offset[4] = { '0' }; char* src = nullptr, *dst = nullptr; int inlen, outlen, size; FILE* srcFile, *dstFile; // 打開被加密源文件 srcFile = fopen("d://comp/csdn.zip", "rb"); // 加密后寫出文件 dstFile = fopen("d://comp/csdn.ecb", "wb+"); // 獲取文件大小 fseek(srcFile, 0, SEEK_END); inlen = ftell(srcFile); if (inlen < 0) { return 0; } fseek(srcFile, 0, SEEK_SET); // ------------------------------------------------------- // 開始加密 src = (char*)calloc(inlen, 1); size = fread(src, 1, inlen, srcFile); std::cout << "讀入字節(jié): " << size << std::endl; // 輸出變量申請(qǐng)的空間額外增加16字節(jié) outlen = (inlen / 16 + 1) * 16; dst = (char*)calloc(outlen, 1); // ECB加密 size = openssl_aes_ecb_enrypt(src, inlen, dst); sprintf(offset, "%d", size - inlen); fwrite(offset, sizeof(char), 4, dstFile); // ------------------------------------------------------- // 輸出加密后的文件或者解密后的文件,文件大小應(yīng)與原始文件一致 size = fwrite(dst, 1, size, dstFile); std::cout << "輸出文件大小: " << size << std::endl; fcloseall(); free(src); free(dst); system("pause"); return 0; }
運(yùn)行后輸出效果圖如下所示;
解密時(shí)同樣需要打開文件,將加密文件csdn.ecb
打開,并解密輸出成csdnde.zip
文件;
int main(int argc, char* argv[]) { // 存放填充字節(jié)數(shù)的數(shù)組 char offset[4] = { '0' }; char* src = nullptr, *dst = nullptr; int inlen, outlen, size; FILE* srcFile, *dstFile; // 打開加密后的文件 srcFile = fopen("d://comp/csdn.ecb", "rb"); // 解密后寫出的文件 dstFile = fopen("d://comp/csdnde.zip", "wb+"); // 獲取文件大小 fseek(srcFile, 0, SEEK_END); inlen = ftell(srcFile); if (inlen < 0) { return 0; } fseek(srcFile, 0, SEEK_SET); // ------------------------------------------------------- fread(offset, sizeof(char), 4, srcFile); inlen -= 4; src = (char*)calloc(inlen, 1); // 從加密后的文件中獲取填充的字節(jié)數(shù) size = fread(src, 1, inlen, srcFile); std::cout << "讀入字節(jié): " << size << std::endl; // 得到原始文件的大小 size = size - atoi(offset); outlen = (inlen / 16 + 1) * 16; dst = (char*)calloc(outlen, 1); // 解密 openssl_aes_ecb_decrypt(src, inlen, dst); // ------------------------------------------------------- // 輸出加密后的文件或者解密后的文件,文件大小應(yīng)與原始文件一致 size = fwrite(dst, 1, size, dstFile); std::cout << "輸出文件大小: " << size << std::endl; fcloseall(); free(src); free(dst); system("pause"); return 0; }
運(yùn)行后輸出效果圖如下所示;
以上就是OpenSSL使用AES實(shí)現(xiàn)文件加解密功能的詳細(xì)內(nèi)容,更多關(guān)于OpenSSL AES文件加解密的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解C語言中typedef和#define的用法與區(qū)別
這篇文章主要給大家介紹了關(guān)于C語言中typedef和#define的的用法、區(qū)別,以及陷阱。文中通過示例進(jìn)行了詳細(xì)講解,感興趣的小伙伴可以了解一下2022-07-07