繁体   English   中英

使用java解密OpenSSL加密数据

[英]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_EncryptUpdateEVP_EncryptFinal ; 如所写的,未填充块的实际使用的唯一加密是由Update完成的。

但是anon_id返回的值不是(JUST)ENCRYPTED PKCS5_PBKDF2_HMAC[_SHA1]PBKDF2算法的一个实现,并且在这里使用它实际上计算了一个缓慢的哈希值

  • recvr_idsmartcard_id连接(更新:显然没有交换)然后使用KEYIV加密三重DES,无论这些代码是什么,作为'passphrase'与

  • hw_id (更新:显然没有交换,因此'意外'类型有效)作为盐,

  • 和PRF = HMAC-SHA1用于ROUNDS (更新:10001)迭代

  • (更新)略微扩展到ANON_ID_BIN_SIZE (22)字节。 (这需要额外的“传递”PBKDF2,这实际上会伤害安全;它会减慢防御者的速度而不会减慢攻击者的速度。)

具有合适PRF(HMAC-SHA1)的PBKDF2 是单向函数,不能反转 ,因为如果您知道或猜测密钥,加密就可以。 如果选择好盐和迭代次数,它的设计成本也很高 32位的盐肯定是偏低的,而且(更新)ROUNDS 10001有点偏低,但并不疯狂。

作为一个更好的例子(对于你作为攻击者)如果32位recvr_idsmartcard_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM