错误的解密错误OpenSSL C++&;QT AES 256 CBC 我试图将明文加密/解密(AES 256 CBC)功能添加到使用Qt和C++构建的个人项目中。我使用的是OpenSSL v1.1.1。我遵循了一些指南,构建了一个类来处理加密和解密。加密似乎工作正常。但解密函数有时会抛出错误:06065064:数字信封例程:EVP_DecryptFinal_ex:坏解密
这项工作:错误的解密错误OpenSSL C++&;QT AES 256 CBC 我试图将明文加密/解密(AES 256 CBC)功能添加到使用Qt和C++构建的个人项目中。我使用的是OpenSSL v1.1.1。我遵循了一些指南,构建了一个类来处理加密和解密。加密似乎工作正常。但解密函数有时会抛出错误:06065064:数字信封例程:EVP_DecryptFinal_ex:坏解密,c++,qt,openssl,C++,Qt,Openssl,这项工作: sample text here.... 这些不包括(.=换行符): 一, 二, 我对QT、C++和OpenSSL都很陌生,所以我不知道如何修复这个问题。p> 我的班级: #define KEYSIZE 32 #define IVSIZE 32 #define BLOCKSIZE 256 #define SALTSIZE 8 QByteArray Encryptor::randBytes(int size) { unsigned char array[size];
sample text here....
这些不包括(.=换行符):
一,
二,
我对QT、C++和OpenSSL都很陌生,所以我不知道如何修复这个问题。p>
我的班级:
#define KEYSIZE 32
#define IVSIZE 32
#define BLOCKSIZE 256
#define SALTSIZE 8
QByteArray Encryptor::randBytes(int size) {
unsigned char array[size];
RAND_bytes(array, size);
QByteArray output = QByteArray(reinterpret_cast<char*> (array), size);
return output;
}
QByteArray Encryptor::encrypt(QByteArray passphrase, QByteArray &content) {
QByteArray msalt = randBytes(SALTSIZE);
int rounds = 1;
unsigned char key[KEYSIZE];
unsigned char iv[IVSIZE];
const unsigned char *password = (const unsigned char*) passphrase.constData();
const unsigned char *salt = (const unsigned char*) msalt.constData();
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, password, passphrase.length(), rounds, key, iv);
if (i != KEYSIZE) {
qCritical() << "EVP_BytesToKey() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(en);
if (!EVP_EncryptInit_ex(en, EVP_aes_256_cbc(), NULL, key, iv)) {
qCritical() << "EVP_EncryptInit_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
char *input = content.data();
char *out;
int length = content.size();
int cLength = length + AES_BLOCK_SIZE;
int fLength = 0;
unsigned char *cipherText = (unsigned char*) malloc(cLength);
if (!EVP_EncryptInit_ex(en, NULL, NULL, NULL, NULL)) {
qCritical() << "EVP_EncryptInit_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
if (!EVP_EncryptUpdate(en, cipherText, &cLength, (unsigned char*) input, length)) {
qCritical() << "EVP_EncryptUpdate() -- " << ERR_error_string(ERR_get_error(), NULL);
free(cipherText);
return QByteArray();
}
if (!EVP_EncryptFinal(en, cipherText + cLength, &fLength)) {
qCritical() << "EVP_EncryptFinal() -- " << ERR_error_string(ERR_get_error(), NULL);
free(cipherText);
return QByteArray();
}
length = cLength + fLength;
out = (char*) cipherText;
EVP_CIPHER_CTX_cipher(en);
free(cipherText);
QByteArray output;
output.append("Salted__");
output.append(msalt);
output.append(out, length);
return output;
}
QByteArray Encryptor::decrypt(QByteArray passphrase, QByteArray &content) {
QByteArray msalt;
if (QString(content.mid(0, 8)) != "Salted__") {
qCritical() << "can not extrect the salt...";
return QByteArray();
}
msalt = content.mid(8, 8);
content = content.mid(16);
int rounds = 1;
unsigned char key[KEYSIZE];
unsigned char iv[IVSIZE];
const unsigned char *password = (const unsigned char*) passphrase.constData();
const unsigned char *salt = (const unsigned char*) msalt.constData();
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, password, passphrase.length(), rounds, key, iv);
if (i != KEYSIZE) {
qCritical() << "EVP_BytesToKey() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(de);
if (!EVP_DecryptInit_ex(de, EVP_aes_256_cbc(), NULL, key, iv)) {
qCritical() << "EVP_DecryptInit_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
char *input = content.data();
int length = content.size();
int pLength = length;
int fLength = 0;
unsigned char *plainText = (unsigned char*) malloc(pLength + AES_BLOCK_SIZE);
if (!EVP_DecryptUpdate(de, plainText, &pLength, (unsigned char*) input, length)) {
qCritical() << "EVP_DecryptUpdate() -- " << ERR_error_string(ERR_get_error(), NULL);
free(plainText);
return QByteArray();
}
if (!EVP_DecryptFinal_ex(de, plainText + pLength, &fLength)) {
qCritical() << "EVP_DecryptFinal_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
free(plainText);
return QByteArray();
}
length = pLength + fLength;
EVP_CIPHER_CTX_cleanup(de);
QByteArray output = QByteArray(reinterpret_cast<char*> (plainText), length);
free(plainText);
return output;
}
#定义键大小32
#定义IVSIZE 32
#定义块大小256
#定义盐大小8
QByteArray加密程序::随机字节(整数大小){
无符号字符数组[大小];
RAND_字节(数组、大小);
QByteArray输出=QByteArray(重新解释投射(数组),大小);
返回输出;
}
QByteArray加密程序::加密(QByteArray密码短语、QByteArray和内容){
QByteArray msalt=randBytes(SALTSIZE);
整数=1;
无符号字符键[KEYSIZE];
无符号字符iv[IVSIZE];
const unsigned char*password=(const unsigned char*)passphrase.constData();
const unsigned char*salt=(const unsigned char*)msalt.constData();
int i=EVP_BytesToKey(EVP_aes_256_cbc(),EVP_sha1(),salt,password,passphrase.length(),rounds,key,iv);
如果(i!=KEYSIZE){
QuestalAuthor()代码>未签名的CHARAR数组[大小];< /COD> -这不是合法的C++。而是使用<代码> QByTurRayEutlook(size,'');RANDYBASEL(RealTytCaseCube(输出.DATA()));返回输出;< /COD> >保存一个副本……但以不必要的初始化为代价。更好的可能是:<代码> QByTurRayOutlook;输出。;RAND_字节(reinterpret_cast(output.data()),size);返回输出;
我建议您搜索“如何调试小程序”作者Eric Lippert。特别是,我认为您希望围绕EVP_BytesToKey之类的东西创建一些小包装,并为它们编写一些已知的答案测试。@MartinBonner谢谢!我会研究一下。这可能不是您的问题,但在encrypt()
函数的末尾,您可以free()
当指针out
指向同一块时,密文所指向的块,并且在该块之后您也在使用它。这可能会导致不可预测的行为。
sample text here... sample text here...
#define KEYSIZE 32
#define IVSIZE 32
#define BLOCKSIZE 256
#define SALTSIZE 8
QByteArray Encryptor::randBytes(int size) {
unsigned char array[size];
RAND_bytes(array, size);
QByteArray output = QByteArray(reinterpret_cast<char*> (array), size);
return output;
}
QByteArray Encryptor::encrypt(QByteArray passphrase, QByteArray &content) {
QByteArray msalt = randBytes(SALTSIZE);
int rounds = 1;
unsigned char key[KEYSIZE];
unsigned char iv[IVSIZE];
const unsigned char *password = (const unsigned char*) passphrase.constData();
const unsigned char *salt = (const unsigned char*) msalt.constData();
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, password, passphrase.length(), rounds, key, iv);
if (i != KEYSIZE) {
qCritical() << "EVP_BytesToKey() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
EVP_CIPHER_CTX *en = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(en);
if (!EVP_EncryptInit_ex(en, EVP_aes_256_cbc(), NULL, key, iv)) {
qCritical() << "EVP_EncryptInit_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
char *input = content.data();
char *out;
int length = content.size();
int cLength = length + AES_BLOCK_SIZE;
int fLength = 0;
unsigned char *cipherText = (unsigned char*) malloc(cLength);
if (!EVP_EncryptInit_ex(en, NULL, NULL, NULL, NULL)) {
qCritical() << "EVP_EncryptInit_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
if (!EVP_EncryptUpdate(en, cipherText, &cLength, (unsigned char*) input, length)) {
qCritical() << "EVP_EncryptUpdate() -- " << ERR_error_string(ERR_get_error(), NULL);
free(cipherText);
return QByteArray();
}
if (!EVP_EncryptFinal(en, cipherText + cLength, &fLength)) {
qCritical() << "EVP_EncryptFinal() -- " << ERR_error_string(ERR_get_error(), NULL);
free(cipherText);
return QByteArray();
}
length = cLength + fLength;
out = (char*) cipherText;
EVP_CIPHER_CTX_cipher(en);
free(cipherText);
QByteArray output;
output.append("Salted__");
output.append(msalt);
output.append(out, length);
return output;
}
QByteArray Encryptor::decrypt(QByteArray passphrase, QByteArray &content) {
QByteArray msalt;
if (QString(content.mid(0, 8)) != "Salted__") {
qCritical() << "can not extrect the salt...";
return QByteArray();
}
msalt = content.mid(8, 8);
content = content.mid(16);
int rounds = 1;
unsigned char key[KEYSIZE];
unsigned char iv[IVSIZE];
const unsigned char *password = (const unsigned char*) passphrase.constData();
const unsigned char *salt = (const unsigned char*) msalt.constData();
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, password, passphrase.length(), rounds, key, iv);
if (i != KEYSIZE) {
qCritical() << "EVP_BytesToKey() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
EVP_CIPHER_CTX *de = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(de);
if (!EVP_DecryptInit_ex(de, EVP_aes_256_cbc(), NULL, key, iv)) {
qCritical() << "EVP_DecryptInit_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
return QByteArray();
}
char *input = content.data();
int length = content.size();
int pLength = length;
int fLength = 0;
unsigned char *plainText = (unsigned char*) malloc(pLength + AES_BLOCK_SIZE);
if (!EVP_DecryptUpdate(de, plainText, &pLength, (unsigned char*) input, length)) {
qCritical() << "EVP_DecryptUpdate() -- " << ERR_error_string(ERR_get_error(), NULL);
free(plainText);
return QByteArray();
}
if (!EVP_DecryptFinal_ex(de, plainText + pLength, &fLength)) {
qCritical() << "EVP_DecryptFinal_ex() -- " << ERR_error_string(ERR_get_error(), NULL);
free(plainText);
return QByteArray();
}
length = pLength + fLength;
EVP_CIPHER_CTX_cleanup(de);
QByteArray output = QByteArray(reinterpret_cast<char*> (plainText), length);
free(plainText);
return output;
}