【问题标题】:How to convert mcrypt_decrypt to openssl_decrypt in PHP? [duplicate]如何在 PHP 中将 mcrypt_decrypt 转换为 openssl_decrypt? [复制]
【发布时间】:2017-07-28 08:01:54
【问题描述】:

我收到了这个代码 sn-p 作为示例,我正试图让它更“现代”一点:

$key='09KzF2qMBy58ZWg137N$I4h6UwJvp!ij';
$encrypted='Chttex_vuYYEK-oKQfwYrVCZYbnNh3tMgwGuK-VOsvt7TjF5M6MIcsE6e8DynZrHuxrmtmIpiN215WygdO-hzXnmx45RXzBWdxk_MkIvNoI=';
$encrypted = urlsafe_b64decode($encrypted);
$decrypted = decrypt($encrypted, $key);
$inflated = gzinflate($decrypted);

echo 'Decrypted: '.$inflated."<br />";

function urlsafe_b64decode($data) {
  return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}

function decrypt($data, $key)
{
    return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB);
}

我正在使用 PHP7 并尝试将其转换为使用 openssl。我获取字符串并通过现有的“urlsafe_b64decode”函数运行它,然后创建另一个“解密”函数:

function decrypt($string, $key)
{
    return openssl_decrypt($string, 'AES-256-ECB', $key);
}

我认为这将是一个相当简单的一对一转换,但它总是返回“false”。有什么想法我可能做错了吗? 提前致谢!

编辑: 由于我使用的服务是 .NET 商店,如果有帮助的话,这里是他们的 .NET 加密示例。

Public Shared Function Encrypt(ByVal data As Byte()) As Byte()
        Dim encrypted As Byte()

        Using rijAlg = New System.Security.Cryptography.AesManaged()
            rijAlg.Key = Encoding.ASCII.GetBytes("encryptionkeyhere")
            rijAlg.Padding = System.Security.Cryptography.PaddingMode.None
            rijAlg.Mode = System.Security.Cryptography.CipherMode.ECB
            Dim encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV)

            Using msEncrypt = New MemoryStream()
                Using csEncrypt = New System.Security.Cryptography.CryptoStream(msEncrypt, encryptor, System.Security.Cryptography.CryptoStreamMode.Write)
                    csEncrypt.Write(data, 0, data.Length)
                End Using

                encrypted = msEncrypt.ToArray()
            End Using
        End Using

        Return encrypted
End Function

更新 2 所以我更新了我的本地服务器以使用 mcrypt,并且能够从我的初始代码 sn-p 中解码加密字符串。这是所需的响应:“sessionid=7bf727043d85e6963e640fb541d886a7454f8091&requestid=1488925528”

在谷歌搜索、stackoverflow-ing 和试验之后,我仍然无法使用 openssl 正确解密字符串。有可能吗?

【问题讨论】:

  • 为什么不简单地用 Mcrypt 解码你的字符串,然后用 OpenSSL 重新加密呢?
  • 不幸的是,它是一个 PHP7 服务器,我无权安装 mcrypt 扩展或更改 ini 文件。
  • 不要使用 ECB 模式,它不安全,请参阅ECB mode,向下滚动到企鹅。而是使用带有随机IV的CBC模式,只需在加密数据前加上IV用于解密即可,它不需要保密。
  • 我尝试使用的服务文档说“使用 AES256-ECB 解密字符串”。模式可以互换吗?如果他们 encrypt 使用 ECB,我可以 decrypt 使用 CBC 吗?
  • 您可能会发现由于您的$key 而无法使用 OpenSSL 解密。我相信你的密钥应该是十六进制的。我发现使用无效密钥使用 Mcrypt 生成的值无法使用 OpenSSL 解密。但是如果使用 Mcrypt 的有效密钥,那么 OpenSSL 可以解密它。

标签: php openssl mcrypt


【解决方案1】:

这不是一个答案,但由于我包含了一大段代码,所以我把它放在这里。它也是从不同的站点提取的,但是我在测试时意外关闭了窗口,无法给予适当的信任。

它还使用不同的密码方法 (ECB)。但是,m也许这对你来说是一个起点。如您所见,运行此代码会引发一些错误,但在底部的 vardump 中,它确实返回了加密的文本字符串。

希望对你有帮助!我必须跑出去!

<?php

$key = "1234541413411111";
$data = "hello world";

$cipher = mcrypt_encrypt(
    MCRYPT_RIJNDAEL_128,
    $key,
    $data,
    MCRYPT_MODE_ECB);

$plain = openssl_decrypt(
    $cipher,
    'aes-128-ecb',
    $key,
    OPENSSL_RAW_DATA | OPENSSL_NO_PADDING
);

//try to detect null padding
if (mb_strlen($iv, '8bit') % mb_strlen($plain, '8bit') == 0) {
    preg_match_all('#([\0]+)$#', $plain, $matches);
    if (mb_strlen($matches[1][0], '8bit') > 1) {
        $plain = rtrim($plain, "\0");
        trigger_error('Detected and stripped null padding. Please double-check results!');
    }
}

var_dump(
    $message,
    bin2hex($cipher),
    $plain,
    mb_strlen($message, '8bit'),
    mb_strlen($plain, '8bit'),
    $message === $plain
);

【讨论】:

    猜你喜欢
    • 2017-10-19
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    • 2014-07-27
    • 2017-09-11
    相关资源
    最近更新 更多