使用java解密OpenSSL加密数据
我试图理解OpenSSL加密。我的要求是使用下面的代码对加密的数据进行解密。它正在为接收方创建匿名ID。我需要把收到的身份证拿回来 根据文档,我了解到加密正在使用使用java解密OpenSSL加密数据,java,c,ssl,encryption,openssl,Java,C,Ssl,Encryption,Openssl,我试图理解OpenSSL加密。我的要求是使用下面的代码对加密的数据进行解密。它正在为接收方创建匿名ID。我需要把收到的身份证拿回来 根据文档,我了解到加密正在使用EVP\u EncryptFinal进行。但是PKCS5\u PBKDF2\u HMAC\u SHA1在做什么 代码使用的是KEY和IV int create_anon_id(uint32_t recvr_id, uint32_t smartcard_id, const char *hw_id, unsigned char *anon_
EVP\u EncryptFinal
进行。但是PKCS5\u PBKDF2\u HMAC\u 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
中返回的值是而不是(仅仅)加密的PKCS5_PBKDF2_HMAC[\u SHA1]
是的一个实现,在这里使用它计算
与recvr\u id
(更新:显然未交换)连接,然后使用smartcard\u id
和密钥
加密三重DES,无论此代码中包含哪些内容,如IV
(更新:显然没有交换,因此“意外”输入有效)作为salthw_id
- 对于
(更新:10001)迭代,PRF=HMAC-SHA1轮次
- (更新)略微扩展到
(22)字节。(这需要额外的“通过”PBKDF2,这实际上会损害安全性;它会减慢防御者的速度而不会减慢攻击者的速度。)ANON\u ID\u BIN\u SIZE
recvr\u id
和smartcard\u id
都只包含16位熵,hw\u id
,并且ROUNDS
为1000,这是在世纪之交编写rfc2898时的建议值,你必须尝试多达256万亿的可能性,一台典型的台式计算机在CPU上每秒可以运行3万次,如果运气和技能好的话,可能是GPU的1000倍,所以这将需要大约3个月的时间
另一方面,如果32位输入是完全熵的,并且轮数为1000000,那么仅用一台计算机是不可能的。如果你有几百万美元花在FPGA(或者更好的ASIC)上,还有发电厂(或者你自己的水电站)的产量来运行它们,那还需要几百万年的时间
更新:对于第10001轮,您很可能处于这两种情况之间,但具体位置在很大程度上取决于输入的熵
总的来说,这可能不会产生预期的结果。如果输出大小小于甚至大致等于输入的熵,则会发生碰撞——产生所需输出的多个输入值(组合),可能是大量(数百万、数十亿等)此类输入。如果您需要原始输入,而不仅仅是生成(伪造)已知输出的某个输入,那么您将需要一些其他方法或条件来从bruteforcing找到的可能输入中进行选择。
更新:对于熵最多为96位的输出22字节,代码非常差的风险可以忽略不计,尽管运气不好,一些错误通过使用正好是一个三重DES数据块(64位或8字节)的输入来掩盖。如果编码正确,则加密将由EVP_EncryptUpdate
和EVP_EncryptFinal
执行;如前所述,未添加块的唯一实际使用的加密由Update
完成
但是anon_id
中返回的值是而不是(仅仅)加密的PKCS5_PBKDF2_HMAC[\u SHA1]
是的一个实现,在这里使用它计算
recvr\u id
与smartcard\u id
(更新:显然未交换)连接,然后使用密钥
和IV
加密三重DES,无论此代码中包含哪些内容,如
hw_id
(更新:显然没有交换,因此“意外”输入有效)作为salt
- 对于
轮次
(更新:10001)迭代,PRF=HMAC-SHA1
- (更新)略微扩展到
ANON\u ID\u BIN\u SIZE
(22)字节。(这需要额外的“通过”PBKDF2,这实际上会损害安全性;它会减慢防御者的速度而不会减慢攻击者的速度。)
PBKDF2具有适当的PRF(HMAC-SHA1是)是一种单向函数,不能反转,因为如果知道或猜测密钥,加密也可以。如果salt和迭代计数选择得当,它的设计成本也会降低。32位的盐肯定是偏低的,而(更新)10001轮有点偏低,但并不疯狂
作为一个更好的例子(对于攻击者来说),如果32位的recvr\u id
和smartcard\u id
都只包含16位熵,hw\u id
,并且ROUNDS
为1000,这是在世纪之交编写rfc2898时的建议值,你必须尝试多达256万亿的可能性,一台典型的台式计算机在CPU上每秒可以运行3万次,如果运气好和技术好的话,可能是GPU的1000倍,所以大约需要3个月的时间