【发布时间】:2011-12-13 08:13:50
【问题描述】:
我正在尝试使用 OpenSSL 使用已知密钥和 IV 从外部源解密 DES 加密文件(其他库并不是真正的选择,因为应用程序已经链接到它,我不想引入新的依赖项)。这是一个 Qt 应用程序,因此数据以 QByteArrays 的形式进出。
这是我目前的代码(设置将解密的数据写入文件以供检查):
AmzHandler::AmzHandler(QByteArray encoded)
{
QByteArray encrypted = QByteArray::fromBase64(encoded);
QByteArray decrypted = decrypt(encrypted);
QFile fred ("decrypted");
fred.open(QFile::WriteOnly);
fred.write(decrypted);
fred.close();
}
QByteArray AmzHandler::decrypt(QByteArray encrypted)
{
DES_cblock key = {0x29, 0xab, 0x9d, 0x18, 0xb2, 0x44, 0x9e, 0x31};
DES_cblock iv = {0x5e, 0x72, 0xd7, 0x9a, 0x11, 0xb3, 0x4f, 0xee};
DES_key_schedule schedule;
unsigned char decrypted[encrypted.size()];
DES_set_odd_parity(&key);
DES_set_key_checked(&key, &schedule);
DES_ncbc_encrypt((unsigned char * )encrypted.constData(), (unsigned char * )decrypted, encrypted.size(), &schedule, &iv, DES_DECRYPT);
return QByteArray::fromRawData((char * )decrypted, length);
}
我的测试输入的输出文件是无意义的,并且在多次运行中不一致。 (我在 Python 中有一个可用的实现,附在这篇文章的底部,用于测试。)我不太确定发生了什么;是我在转换为 char 时犯了一些简单的错误,还是在滥用 OpenSSL。
编辑:已解决。原来DES_set_odd_parity(&key); 行不见了。添加它就可以了。
这是 Python 中的工作代码:
def AmzHandler(encoded):
encrypted = base64.b64decode(encoded)
d = pyDes.des(hex_to_str("29AB9D18B2449E31"), mode=pyDes.CBC, IV=hex_to_str("5E72D79A11B34FEE"))
decrypted = d.decrypt(encrypted)
f = open("decrypted-py", "w")
f.write(decrypted)
f.close()
【问题讨论】:
-
这看起来很可疑:
unsigned char *decrypted[encrypted.size()];。它应该是一个指针,或者一个数组。 -
@vhallac 好的。我现在尝试了
unsigned char decrypted[encrypted.size()];和(在this 之后)unsigned char *decrypted; decrypted = (unsigned char *) malloc (encrypted.size());。两者都产生不同大小的输出,但仍为数百字节,而且显然不正确。 -
QByteArray可能需要数组的长度。仅从缓冲区地址无法确定。 -
@vhallac 啊,好的。我已将其更改为使用 QByteArray::fromRawData(),它接受一个参数来表示它正在读取的数据的大小。但是,输出仍然是无意义的(无论我使用哪种解密声明的变体)。
-
其余的代码看起来没问题。如果我是你,我会仔细检查钥匙。您也可以尝试通过自己加密来仔细检查您的代码,以确保它确实可以在此之前解密。