簡體   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