首页 文章

用PHP解密C#RIJNDAEL编码文本

提问于
浏览
0

作为授权过程的一部分,我需要解密字符串 .

该文档指定使用以下设置加密授权字符串:

  • 填充输入数据: PKCS*7

  • 密码字节数组长度为32个字节 . 密码字符串转换为UTF-16编码的字节数组,然后字节数组用零填充,最长为32个字节 . 更长的密码被截断 .

C#示例:

/// <summary>
    /// Decrypts a string.
    /// </summary>
    /// <param name="content">The string to decrypt.</param>
    /// <param name="password">The password to use.</param>
    /// <returns>The decrypted string.</returns>
    private static string DecryptString(string content, string password)
    {
        Rijndael aes;
        byte[] retVal = null;
        byte[] contentBytes;
        byte[] passwordBytes;
        byte[] ivBytes;

        try
        {
            contentBytes = Convert.FromBase64String(content);

            //Create the password and initial vector bytes
            passwordBytes = new byte[32];
            ivBytes = new byte[16];
            Array.Copy(Encoding.Unicode.GetBytes(password), passwordBytes, Encoding.Unicode.GetBytes(password).Length);
            Array.Copy(passwordBytes, ivBytes, 16);

            //Create the cryptograpy object
            using (aes = Rijndael.Create())
            {
                aes.Key = passwordBytes;
                aes.IV = ivBytes;
                aes.Padding = PaddingMode.PKCS7;

                //Decrypt
                retVal = aes.CreateDecryptor().TransformFinalBlock(contentBytes, 0, contentBytes.Length);
            }
        }
        catch
        {
        }

        return Encoding.Unicode.GetString(retVal);
    }

这里讨论了相同的功能,但对于JAVA:Decrypt C# RIJNDAEL encoded text

我尝试使用以下函数解密它,但结果与预期的不同:

function decrypt($string, $pass){
    $iv = substr($pass, 0, 16);
    $data =  mcrypt_decrypt(MCRYPT_RIJNDAEL_256,
                        $pass,
                        base64_decode($string),
                        MCRYPT_MODE_CBC,
                        $iv);
    $pad = ord($data[strlen($data) - 1]);
    return substr($data, 0, -$pad);
}

ecrypted字符串 "7iTdZnp0DtGnIfwwqY4W/glbLLVZ0+asVLAuz13PzrW0wM6HC7rNuQvcG8JDSehyYeBJARdXHgLo9hRL9sBz3fN5LJ8cro3o0kFnAao2YRU="

应该解密

"ldYWMFlSbcki6LMl3rkNfGavnt8VqmZd"

使用密码 "GAT"

我认为它与密码/ iv /编码有关

1 回答

  • 0
    function decrypt($string, $pass)
    {
        $encodedPass = mb_convert_encoding($pass, 'utf-16le');
        $encodedPass = substr($encodedPass, 0, 32);
        $encodedPass = str_pad($encodedPass, 32, "\0", STR_PAD_RIGHT);
        $iv = substr($encodedPass, 0, 16);
    
        $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,
                            $encodedPass,
                            base64_decode($string),
                            MCRYPT_MODE_CBC,
                            $iv);
        $pad = ord($data[strlen($data) - 1]);
        return substr($data, 0, -$pad);
    }
    

    在PHP中, MCRYPT_RIJNDAEL_128 / MCRYPT_RIJNDAEL_256 不是键的大小,而是块的大小(请参阅https://www.chilkatsoft.com/p/php_aes.asp) . C#通常使用16字节块,所以 MCRYPT_RIJNDAEL_128 . 密钥的大小是自动检测的 . 请注意,我已在方法内移动了密码的编码/大小调整 .

相关问题