从C#代码中寻找PHP中相似的代码(AES-256解密)

3

我一直在尝试将以下C#代码中的类似模式应用到PHP中。我已经花了7天时间,在我的EPin API应用程序中实现了简单的加密通信。问题是,PHP脚本的响应却是空白的。

public static string AESDecryptText(string input, string key)
{
    // Get the bytes of the string
    byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
    byte[] keyBytes = Encoding.UTF8.GetBytes(key);
    keyBytes = SHA256.Create().ComputeHash(keyBytes);

    byte[] bytesDecrypted = AESDecrypt(bytesToBeDecrypted, keyBytes);

    string result = Encoding.UTF8.GetString(bytesDecrypted);

    return result;
}

public static byte[] AESDecrypt(byte[] bytesToBeDecrypted, byte[] keyBytes)
{
    byte[] decryptedBytes = null;

    // Set your salt here, change it to meet your flavor:
    // The salt bytes must be at least 8 bytes.
    byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

    using (MemoryStream ms = new MemoryStream())
    {
        using (RijndaelManaged AES = new RijndaelManaged())
        {
            AES.KeySize = 256;
            AES.BlockSize = 128;

            var key = new Rfc2898DeriveBytes(keyBytes, saltBytes, 1000);
            AES.Key = key.GetBytes(AES.KeySize / 8);
            AES.IV = key.GetBytes(AES.BlockSize / 8);

            AES.Mode = CipherMode.CBC;

            using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                cs.Close();
            }
            decryptedBytes = ms.ToArray();
        }
    }

    return decryptedBytes;
}

来自其他线程的我的PHP代码...

function DecryptString($content, $password = 
 '4J2lh3Lz4q6ACo16VrL1oLDnh3k7G1KaXliUPVPV8o0='){


 $password = mb_convert_encoding($password, "utf-16le");
        $padding = 32 - (strlen($password) % 32);
        $password .= str_repeat("\0", $padding);
        $iv = substr($password, 0, 8);
        $data = base64_decode($content);

       $decrypted  = openssl_decrypt($data, 'AES-256-CBC', $password, 
 OPENSSL_RAW_DATA, $iv);
        $decrypted = mb_convert_encoding($decrypted, "utf-8", "utf-16le");
        return $decrypted;
}


 function decryption(){

    $password = "4J2lh3Lz4q6ACo16VrL1oLDnh3k7G1KaXliUPVPV8o0=";
    $content = "wKamNpehMEqJQ4NcUueNuXq1PbupsxwEvwcJ0CeI+8Q=";
    echo $this->DecryptString($content, $password);

    }

每次打印时,都显示空白。请帮忙解决这个问题。

  1. $password 似乎是 base64 编码的字节,我认为在使用之前应该先解码它。2) 你应该使用 hash_pbkdf2 来生成密钥。3) 在我的答案 porting-c-sharp-aes-256-decryption-to-php 中,我使用 mb_convert_encoding 解码 c# Unicode 编码的字符串,但你不需要那个。4) 不要复制粘贴从互联网上找到的代码并期望其自动工作。5) 即使它以某种方式起作用,你也不应该使用它,因为它不安全。
- t.m.adam
function DecryptString($content, $password = '4J2lh3Lz4q6ACo16VrL1oLDnh3k7G1KaXliUPVPV8o0='){ // $password = mb_convert_encoding($password, "utf-16le"); $password = base64_decode($password); $padding = 32 - (strlen($password) % 32); $password .= str_repeat("\0", $padding); $iv = substr($password, 0, 16);$data = base64_decode($content); $decrypted = openssl_decrypt($data, 'AES-256-CBC', $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv); var_dump( $decrypted);} .. 仍然得到无法理解的输出。请在此方面给我帮助 @t.m.adam - VMG Dev Team
1个回答

0
在您的 C# 代码中,您使用 SHA256 来哈希密码,并使用 Rfc2898DeriveBytes 创建密钥和 IV。PHP 类似的函数是 hash(使用 sha256)和 hash_pbkdf2
C# 中 AESDecryptText 方法的 PHP 等效方法:
function AESDecryptText($content, $password){
    $password = hash('sha256', $password, true);
    $salt = pack("C*",1,2,3,4,5,6,7,8);
    $bytes = hash_pbkdf2("sha1", $password, $salt, 1000, 48, true);
    $key = substr($bytes, 0, 32);
    $iv = substr($bytes, 32, 16);
    return openssl_decrypt($content, 'AES-256-CBC', $key, 0, $iv);
}

一些注意事项:

  • 每个密码的盐值应该是唯一的。
  • 初始化向量(IV)应该是随机的,与密码或密钥无关。
    您可以使用 openssl_random_pseudo_bytes 来创建随机字节。
  • 盐值和 IV 不必保密,您可以将它们存储在密文旁边。
  • 您应该考虑使用 HMAC 对您的密文进行身份验证。
    您可以使用 hash_hmac 来实现此目的。

太好了。需要帮忙吗,先生? - VMG Dev Team

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接