[英]Decrypt OpenSSL encrypted data using java
我试图了解OpenSSL加密。 对我的要求是解密使用以下代码加密的数据。 它正在为接收器创建一个匿名ID。 我需要收回身份证。
根据文档,我了解使用EVP_EncryptFinal
加密。 但是什么是PKCS5_PBKDF2_HMAC_SHA1
呢?
代码使用KEY和IV。
int create_anon_id(uint32_t recvr_id, uint32_t smartcard_id, const char *hw_id, unsigned char *anon_id)
{
EVP_CIPHER_CTX ctx;
unsigned char ibuf[sizeof(recvr_id) + sizeof(smartcard_id)] = {};
unsigned char obuf[sizeof(ibuf) * 2] = {};
int olen = sizeof(obuf);
/* Convert to big endian. */
recvr_id = bswap32(recvr_id);
smartcard_id = bswap32(smartcard_id);
hw_id = bswap32(hw_id);
/* Fill input buffer with recvr_id | smartcard_id */
memcpy(ibuf, &recvr_id, sizeof(recvr_id));
memcpy(ibuf + sizeof(recvr_id), &smartcard_id, sizeof(smartcard_id));
if (EVP_EncryptInit(&ctx, EVP_des_ede3_cbc(), KEY, IV) == 1)
{
if (EVP_EncryptUpdate(&ctx, obuf, &olen, ibuf, sizeof(ibuf)) == 1)
{
olen = sizeof(obuf) - olen;
if (EVP_EncryptFinal(&ctx, obuf + sizeof(obuf) - olen, &olen) == 1)
{
return PKCS5_PBKDF2_HMAC_SHA1((const char *)obuf, olen, (unsigned char *)hw_id, HW_ID_SIZE, ROUNDS, ANON_ID_BIN_SIZE, anon_id);
}
}
}
}
该代码相当差,尽管运气不好,一些错误被使用输入掩盖,输入恰好是一个三重DES数据块(64位或8字节)。 如果编码正确,加密将由EVP_EncryptUpdate
和EVP_EncryptFinal
; 如所写的,未填充块的实际使用的唯一加密是由Update
完成的。
但是anon_id
返回的值不是(JUST)ENCRYPTED 。 PKCS5_PBKDF2_HMAC[_SHA1]
是PBKDF2算法的一个实现,并且在这里使用它实际上计算了一个缓慢的哈希值
recvr_id
与smartcard_id
连接(更新:显然没有交换)然后使用KEY
和IV
加密三重DES,无论这些代码是什么,作为'passphrase'与
hw_id
(更新:显然没有交换,因此'意外'类型有效)作为盐,
和PRF = HMAC-SHA1用于ROUNDS
(更新:10001)迭代
(更新)略微扩展到ANON_ID_BIN_SIZE
(22)字节。 (这需要额外的“传递”PBKDF2,这实际上会伤害安全;它会减慢防御者的速度而不会减慢攻击者的速度。)
具有合适PRF(HMAC-SHA1)的PBKDF2 是单向函数,不能反转 ,因为如果您知道或猜测密钥,加密就可以。 如果选择好盐和迭代次数,它的设计成本也很高 。 32位的盐肯定是偏低的,而且(更新)ROUNDS 10001有点偏低,但并不疯狂。
作为一个更好的例子(对于你作为攻击者)如果32位recvr_id
和smartcard_id
每个只包含16位熵,那么hw_id
也是如此,并且ROUNDS
是1000,这是在转弯处写入rfc2898时的推荐值在本世纪,你必须尝试高达256万亿的可能性,典型的台式电脑每秒可以在CPU中运行3万,而运气和技能可能是GPU的千倍,因此需要大约3个月。
另一方面,如果32位输入是完全熵并且ROUNDS
是1000000,那么仅使用计算机是不可能的。 如果你花费数百万美元用于FPGA(甚至更好的ASIC),以及发电厂(或者你自己的水电大坝)的输出来运行它们,它仍然需要数百万年。
更新:使用ROUNDS 10001,您最有可能处于这些情况之间,但只是在很大程度上取决于输入的熵。
并且通常这可能无论如何都不会产生期望的结果。 如果输出大小小于或甚至大致等于输入的熵,则会发生冲突 - 产生所需输出的多个输入值(组合),可能是这些输入的大量(数百万,数十亿等) 。 如果需要原始输入,而不是仅仅一些输入,其产生(伪造)已知的输出,就需要一些其它方法或标准的穷举的发现可能的输入中进行选择。 更新:对于输出22字节,最多96位熵,这种风险可以忽略不计 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.