欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OpenSSL使用AES實(shí)現(xiàn)文件加解密功能

 更新時(shí)間:2023年11月29日 08:58:09   作者:微軟技術(shù)分享  
AES是一種對(duì)稱加密算法,它是目前廣泛使用的加密算法之一,意味著加密和解密使用相同的密鑰,這就要求密鑰的安全性非常重要,因?yàn)槿魏螕碛忻荑€的人都能進(jìn)行加密和解密操作,本文給大家介紹了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)。

  1. 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)行并行加密處理。
  2. 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語言八大排序算法(收藏)

    必須知道的C語言八大排序算法(收藏)

    這篇文章主要介紹了C語言八大排序算法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-10-10
  • C++實(shí)現(xiàn)從輸入中讀取字符串

    C++實(shí)現(xiàn)從輸入中讀取字符串

    這篇文章主要介紹了C++實(shí)現(xiàn)從輸入中讀取字符串的實(shí)現(xiàn)思路和具體代碼,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下
    2016-05-05
  • C++類URL編碼和解碼使用技巧

    C++類URL編碼和解碼使用技巧

    在項(xiàng)目開發(fā)過程中,經(jīng)常會(huì)使用到c++ 的url編碼和解碼,本文將以此問題詳細(xì)介紹使用技巧,需要的朋友可以參考下
    2012-11-11
  • C語言經(jīng)典指針筆試題詳解

    C語言經(jīng)典指針筆試題詳解

    今天博主來講解4道經(jīng)典的指針筆試題,很多朋友沒有深刻理解函數(shù)傳參知識(shí)都會(huì)在這些題目上出錯(cuò),下面話不多說,我們開始
    2021-10-10
  • C/C++中帶空格字符串的輸入講解

    C/C++中帶空格字符串的輸入講解

    這篇文章主要給大家介紹了關(guān)于如何解決C++中帶空格字符串的輸入問題,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧
    2021-09-09
  • 詳解C語言中typedef和#define的用法與區(qū)別

    詳解C語言中typedef和#define的用法與區(qū)別

    這篇文章主要給大家介紹了關(guān)于C語言中typedef和#define的的用法、區(qū)別,以及陷阱。文中通過示例進(jìn)行了詳細(xì)講解,感興趣的小伙伴可以了解一下
    2022-07-07
  • C語言中K-means算法實(shí)現(xiàn)代碼

    C語言中K-means算法實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了C語言中K-means算法的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C語言刪除輸入字符串中的空格示例代碼

    C語言刪除輸入字符串中的空格示例代碼

    最近工作中遇到了需求,要?jiǎng)h除字符串中的所有空格,就要篩選出空格字符,這篇文章主要給大家介紹了關(guān)于利用C語言刪除輸入字符串中的空格的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • C語言超細(xì)致講解循環(huán)語句

    C語言超細(xì)致講解循環(huán)語句

    我們說到當(dāng)滿足特定條件時(shí),就會(huì)執(zhí)行if語句或者switch語句后面的語句,否則不執(zhí)行,但是這只能執(zhí)行一次,在日常生活中,有些事情是需要重復(fù)去做的,C語句就為此引入了循環(huán)語句。所以今天繼續(xù)為大家分享C語言循環(huán)家族
    2022-05-05
  • C語言 深入淺出講解指針的使用

    C語言 深入淺出講解指針的使用

    指針是C語言中一個(gè)非常重要的概念,也是C語言的特色之一。使用指針可以對(duì)復(fù)雜數(shù)據(jù)進(jìn)行處理,能對(duì)計(jì)算機(jī)的內(nèi)存分配進(jìn)行控制,在函數(shù)調(diào)用中使用指針還可以返回多個(gè)值
    2022-03-03

最新評(píng)論