将 Ruby AES256 解密函数转换为 PHP

发布于 2024-08-09 20:58:35 字数 1151 浏览 1 评论 0原文

我在 Ruby 中有以下函数可以解密一些数据:

def decrypt(key, iv, cipher_hex)
    cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')

    cipher.decrypt
    cipher.key = key.gsub(/(..)/){|h| h.hex.chr}
    cipher.iv = iv.gsub(/(..)/){|h| h.hex.chr}

    decrypted_data = cipher.update(cipher_hex.gsub(/(..)/){|h| h.hex.chr})
    decrypted_data << cipher.final

    return decrypted_data
end

我试图在 PHP 中做同样的事情,但我不确定我做错了什么。这就是我得到的:

function decrypt_data($key, $iv, $cipher_hex) {
    return mcrypt_decrypt(
        MCRYPT_RIJNDAEL_128, 
        hex_to_str($key), 
        hex_to_str($cipher_hex), 
        MCRYPT_MODE_CBC, 
        hex_to_str($iv)
    );
}

function hex_to_str($hex_str) {
    preg_match_all('/(..)/', $hex_str, $matches);

    $to_return = '';
    foreach ($matches[1] as $val)
        $to_return .= chr(hexdec($val));
    return $to_return;
}

输出最终变成了垃圾,而不是我正在寻找的字符串。有想法吗?

在我们开始之前,将其切换到 MCRYPT_RIJNDAEL_256 似乎没有帮助,只会导致它抱怨 iv 与块大小不一样长。我相信在这种情况下 128 是正确的,因为 此网站 说 128/256 是块大小的指示,而不是密钥大小。

I have the following function in Ruby that decrypts a bit of data:

def decrypt(key, iv, cipher_hex)
    cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')

    cipher.decrypt
    cipher.key = key.gsub(/(..)/){|h| h.hex.chr}
    cipher.iv = iv.gsub(/(..)/){|h| h.hex.chr}

    decrypted_data = cipher.update(cipher_hex.gsub(/(..)/){|h| h.hex.chr})
    decrypted_data << cipher.final

    return decrypted_data
end

I'm trying to do the exact same thing in PHP, but I'm not sure what I'm doing wrong. Here's what I've got:

function decrypt_data($key, $iv, $cipher_hex) {
    return mcrypt_decrypt(
        MCRYPT_RIJNDAEL_128, 
        hex_to_str($key), 
        hex_to_str($cipher_hex), 
        MCRYPT_MODE_CBC, 
        hex_to_str($iv)
    );
}

function hex_to_str($hex_str) {
    preg_match_all('/(..)/', $hex_str, $matches);

    $to_return = '';
    foreach ($matches[1] as $val)
        $to_return .= chr(hexdec($val));
    return $to_return;
}

The output just ends up being garbage, not the string I'm looking for. Ideas?

And before we even start, switching it to MCRYPT_RIJNDAEL_256 doesn't seem help and just causes it to complain about the iv not being as long as the block size. I believe 128 is correct in this case since this site says that the 128/256 is an indication of the block size, not the key size.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独木成林 2024-08-16 20:58:35

就我个人而言,我对自制的 hex_to_str 函数有点怀疑 - 为什么不直接使用 pack('H*', $key) 呢?

Personally I'm a little suspicious of the homebrewed hex_to_str function - why not just use pack('H*', $key)?

浅唱々樱花落 2024-08-16 20:58:35

事实证明,一切正常,只是我的测试数据不好。我所做的两个更改是使用 pack() (根据 caf 的建议)并删除末尾的填充字符。

function decrypt_data($key, $iv, $cipher_hex) {
    return rtrim(
        mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128, 
            pack('H*', $key), 
            pack('H*', $cipher_hex), 
            MCRYPT_MODE_CBC, 
            pack('H*', $iv)
        ), 
        "\x00..\x1F"
    );
}

It turns out that it was working fine, it's just that my test data was bad. The two changes I made were using pack() (at caf's suggestion) and dropping the padding characters from the end.

function decrypt_data($key, $iv, $cipher_hex) {
    return rtrim(
        mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128, 
            pack('H*', $key), 
            pack('H*', $cipher_hex), 
            MCRYPT_MODE_CBC, 
            pack('H*', $iv)
        ), 
        "\x00..\x1F"
    );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文