C++ openssl AES/CBC/PKCS7Padding 256位加密 解密示例 MD5示例
C++ openssl AES/CBC/PKCS7Padding 256位加密 解密示例
加密
为了确保 AES 加密使用 AES/CBC/PKCS7Padding
,我们需要确保在加密过程中正确处理填充。OpenSSL 的 AES_cbc_encrypt
函数并不自动处理填充,因此我们需要手动实现 PKCS7 填充。
以下是更新后的代码,确保在加密时使用 PKCS7 填充:
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <stdexcept>
void printHex(const std::vector<unsigned char>& data) {
for (unsigned char byte : data) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte;
}
std::cout << std::endl;
}
// PKCS7 填充
std::vector<unsigned char> pkcs7_pad(const std::vector<unsigned char>& data, size_t blockSize) {
size_t paddingSize = blockSize - (data.size() % blockSize);
std::vector<unsigned char> paddedData(data);
paddedData.insert(paddedData.end(), paddingSize, static_cast<unsigned char>(paddingSize));
return paddedData;
}
std::vector<unsigned char> aes_encrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& plaintext) {
AES_KEY encryptKey;
std::vector<unsigned char> paddedPlaintext = pkcs7_pad(plaintext, AES_BLOCK_SIZE);
std::vector<unsigned char> ciphertext(paddedPlaintext.size());
// 设置加密密钥
if (AES_set_encrypt_key(key.data(), 256, &encryptKey) < 0) {
throw std::runtime_error("Failed to set encryption key");
}
// 加密
AES_cbc_encrypt(paddedPlaintext.data(), ciphertext.data(), paddedPlaintext.size(), &encryptKey, const_cast<unsigned char*>(iv.data()), AES_ENCRYPT);
return ciphertext;
}
int main() {
// 密钥
std::vector<unsigned char> key = {
0xDF, 0xAB, 0x3A, 0xC1, 0xA8, 0xD6, 0xA4, 0xE4,
0x30, 0x63, 0x64, 0xDC, 0x06, 0x93, 0xE2, 0x26,
0x20, 0x80, 0x72, 0xF7, 0x68, 0x89, 0x5E, 0xD5,
0xFB, 0x68, 0x49, 0x93, 0xE0, 0x9A, 0x42, 0xA6
};
// 明文
std::vector<unsigned char> plaintext = {
0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F,
0x72, 0x6C, 0x64, 0x21, 0x20, 0x54, 0x68, 0x69,
0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74,
0x65, 0x73, 0x74, 0x20, 0x6D, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65
};
// 初始向量
std::vector<unsigned char> iv = {
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
};
try {
std::vector<unsigned char> ciphertext = aes_encrypt(key, iv, plaintext);
std::cout << "Encrypted ciphertext: ";
printHex(ciphertext);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
说明:
- PKCS7 填充:
pkcs7_pad
函数实现了 PKCS7 填充。它计算需要添加的填充字节数,并在明文末尾添加相应数量的字节。 - 加密过程:在加密之前,首先对明文进行填充,然后使用
AES_cbc_encrypt
进行加密。 - 输出:加密后的密文以十六进制格式输出。
确保在项目中链接 OpenSSL 库,并根据您的项目设置进行相应的调整。这样可以确保加密后的密文符合 AES/CBC/PKCS7Padding 的要求。
解密
确保使用 AES/CBC/PKCS7Padding
。我们将添加解密函数,并在 main
函数中演示如何使用它。
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <stdexcept>
void printHex(const std::vector<unsigned char>& data) {
for (unsigned char byte : data) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte;
}
std::cout << std::endl;
}
// PKCS7 填充
std::vector<unsigned char> pkcs7_pad(const std::vector<unsigned char>& data, size_t blockSize) {
size_t paddingSize = blockSize - (data.size() % blockSize);
std::vector<unsigned char> paddedData(data);
paddedData.insert(paddedData.end(), paddingSize, static_cast<unsigned char>(paddingSize));
return paddedData;
}
// PKCS7 去填充
std::vector<unsigned char> pkcs7_unpad(const std::vector<unsigned char>& data) {
size_t paddingSize = data.back();
return std::vector<unsigned char>(data.begin(), data.end() - paddingSize);
}
std::vector<unsigned char> aes_encrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& plaintext) {
AES_KEY encryptKey;
std::vector<unsigned char> paddedPlaintext = pkcs7_pad(plaintext, AES_BLOCK_SIZE);
std::vector<unsigned char> ciphertext(paddedPlaintext.size());
// 设置加密密钥
if (AES_set_encrypt_key(key.data(), 256, &encryptKey) < 0) {
throw std::runtime_error("Failed to set encryption key");
}
// 加密
AES_cbc_encrypt(paddedPlaintext.data(), ciphertext.data(), paddedPlaintext.size(), &encryptKey, const_cast<unsigned char*>(iv.data()), AES_ENCRYPT);
return ciphertext;
}
std::vector<unsigned char> aes_decrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& ciphertext) {
AES_KEY decryptKey;
std::vector<unsigned char> decryptedData(ciphertext.size());
// 设置解密密钥
if (AES_set_decrypt_key(key.data(), 256, &decryptKey) < 0) {
throw std::runtime_error("Failed to set decryption key");
}
// 解密
AES_cbc_encrypt(ciphertext.data(), decryptedData.data(), ciphertext.size(), &decryptKey, const_cast<unsigned char*>(iv.data()), AES_DECRYPT);
// 去填充
return pkcs7_unpad(decryptedData);
}
int main() {
// 密钥
std::vector<unsigned char> key = {
0xDF, 0xAB, 0x3A, 0xC1, 0xA8, 0xD6, 0xA4, 0xE4,
0x30, 0x63, 0x64, 0xDC, 0x06, 0x93, 0xE2, 0x26,
0x20, 0x80, 0x72, 0xF7, 0x68, 0x89, 0x5E, 0xD5,
0xFB, 0x68, 0x49, 0x93, 0xE0, 0x9A, 0x42, 0xA6
};
// 明文
std::vector<unsigned char> plaintext = {
0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F,
0x72, 0x6C, 0x64, 0x21, 0x20, 0x54, 0x68, 0x69,
0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74,
0x65, 0x73, 0x74, 0x20, 0x6D, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65
};
// 初始向量
std::vector<unsigned char> iv = {
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
};
try {
// 加密
std::vector<unsigned char> ciphertext = aes_encrypt(key, iv, plaintext);
std::cout << "Encrypted ciphertext: ";
printHex(ciphertext);
// 解密
std::vector<unsigned char> decryptedText = aes_decrypt(key, iv, ciphertext);
std::cout << "Decrypted plaintext: ";
printHex(decryptedText);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
说明:
-
PKCS7 填充和去填充:
pkcs7_pad
函数用于在加密前对明文进行填充。pkcs7_unpad
函数用于在解密后去除填充。
-
AES 加密和解密:
aes_encrypt
函数实现 AES 加密,使用 CBC 模式和 PKCS7 填充。aes_decrypt
函数实现 AES 解密,使用 CBC 模式,并在解密后去除填充。
-
主函数:
- 在
main
函数中,首先加密明文,然后解密密文,并输出加密后的密文和解密后的明文。
- 在
确保在项目中链接 OpenSSL 库,并根据您的项目设置进行相应的调整。这样可以确保加密和解密过程符合 AES/CBC/PKCS7Padding 的要求。
C++ 用openssl计算字符串的md5
要在 C++ 中使用 OpenSSL 计算字符串的 MD5 哈希,可以按照以下步骤进行。首先,确保你已经安装了 OpenSSL 库。然后,你可以使用以下代码示例来计算字符串的 MD5 值:
#include <iostream>
#include <openssl/md5.h>
std::string calculateMD5(const std::string &input) {
unsigned char digest[MD5_DIGEST_LENGTH];
MD5((unsigned char*)input.c_str(), input.size(), digest);
// 将结果转换为十六进制字符串
char md5String[33];
for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
sprintf(&md5String[i * 2], "%02x", (unsigned int)digest[i]);
}
return std::string(md5String);
}
int main() {
std::string input = "hello world";
std::string md5Hash = calculateMD5(input);
std::cout << "MD5 of \"" << input << "\" is: " << md5Hash << std::endl;
return 0;
}
代码说明:
- 包含头文件:引入
openssl/md5.h
以使用 MD5 函数。 - 计算 MD5:
calculateMD5
函数接受一个字符串输入,计算其 MD5 值,并返回十六进制格式的字符串。 - 主函数:在
main
函数中,定义一个输入字符串并调用calculateMD5
函数,然后输出结果。
编译和运行:
确保在编译时链接 OpenSSL 库,例如:
g++ -o md5_example md5_example.cpp -lssl -lcrypto
然后运行生成的可执行文件:
./md5_example
这将输出字符串 “hello world” 的 MD5 哈希值。