【问题标题】:AES128 Encryption using PHP mcrypt is not outputting same as ASP.net使用 PHP mcrypt 的 AES128 加密输出与 ASP.net 不同
【发布时间】:2014-08-17 14:24:28
【问题描述】:

我有一个 PHP 应用程序需要加密一个由 ASP.net Web 服务使用的质询字符串,但是我的 PHP 实现的输出没有被 .net 正确解密。就像这个关于 iOS 和 .net 的问题一样:AES128 bit encryption string is not similar as on .net

为什么输出不同,我可以对我的 PHP 做些什么来输出与 .net 相同的结果?

我的 PHP 代码如下所示:

$key = '128bit-16bytekey';
$value = '128bit-16byteval';
function fnEncrypt($value, $key)
{
    $ivsize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
    $iv     = mcrypt_create_iv($ivsize);
    return base64_encode(
            mcrypt_encrypt(
                MCRYPT_RIJNDAEL_128,
                $key, $value, 
                MCRYPT_MODE_ECB,$iv
            ));
}

.net 像这样

public static string EncryptData(string plainText)
    {
        string encryptionKey = AppConstants.AES_ENCRYPTDECRYPT_KEY;
        // Convert our plaintext into a byte array.
        // Let us assume that plaintext contains UTF8-encoded characters.
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

        // Use the password to generate pseudo-random bytes for the encryption
        // key. Specify the size of the key in bytes (instead of bits).
        ASCIIEncoding encoding = new ASCIIEncoding();
        byte[] keyBytes = new byte[16];

        byte[] tempKey = encoding.GetBytes(encryptionKey);

        for (int i = 0; i < keyBytes.Length; i++)
        {
            if (i < tempKey.Length)
            {
                keyBytes[i] = tempKey[i];
            }
            else
            {
                keyBytes[i] = 0;
            }
        }

        // Create uninitialized Rijndael encryption object.
        RijndaelManaged symmetricKey = new RijndaelManaged();

        //AesManaged symmetricKey = new AesManaged();


        //symmetricKey.Padding = PaddingMode.PKCS7;
        // It is reasonable to set encryption mode to Cipher Block Chaining
        // (CBC). Use default options for other symmetric key parameters.
        symmetricKey.Mode = CipherMode.ECB;

        // Generate encryptor from the existing key bytes and initialization 
        // vector. Key size will be defined based on the number of the key 
        // bytes.

        //ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes,initVectorBytes);
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, null);

        // Define memory stream which will be used to hold encrypted data.
        MemoryStream memoryStream = new MemoryStream();

        // Define cryptographic stream (always use Write mode for encryption).
        CryptoStream cryptoStream = new CryptoStream(memoryStream,
                                                     encryptor,
                                                     CryptoStreamMode.Write);
        // Start encrypting.
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

        // Finish encrypting.
        cryptoStream.FlushFinalBlock();

        // Convert our encrypted data from a memory stream into a byte array.
        byte[] cipherTextBytes = memoryStream.ToArray();

        // Close both streams.
        memoryStream.Close();
        cryptoStream.Close();

        // Convert encrypted data into a base64-encoded string.
        string cipherText = Convert.ToBase64String(cipherTextBytes);

        // Return encrypted string.
        return cipherText;
    }

示例输出

PHP : Q54nP/tXq2rDTUwWw4ckkg==

.net : Q54nP/tXq2rDTUwWw4ckkpSt9CQiIzsg2xsQEndcqc8=

PHP : DQZdAB/lABXVOOoCdNM6HQ==

.net : DQZdAB/labXVOOoCdNM6HZSt9CQiIzsg2xsQEndcqc8=

正如上面提到的问题一样,.net 输出的右侧总是相同的,左侧在两个实现之间是一致的。我很确定 IV 是无关紧要的,它与 mcrypt 中填充的处理方式有关。

如果我在 PHP 中解密任何一个输出,它都会返回相同的正确结果。

谁能解释一下?我无法更改 .net 应用程序。谢谢!

【问题讨论】:

    标签: php asp.net encryption mcrypt


    【解决方案1】:

    这是由applied in .net 填充造成的。您可以通过在 .net 代码中添加以下行来克服这个问题:

    symmetricKey.Padding = PaddingMode.None;
    

    或者您可以更改 PHP 代码以获得相同的加密字符串:

    // Add the lines below to your fnEncrypt function
    $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
    $len = strlen($value);
    $padding = $block - ($len % $block);
    $value .= str_repeat(chr($padding),$padding);
    

    PHP 手册页的其中一个 cmets 中描述了类似的问题:http://www.php.net//manual/en/function.mcrypt-encrypt.php#47973

    【讨论】:

      猜你喜欢
      • 2018-09-28
      • 2014-02-01
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      • 2017-07-10
      • 2014-08-15
      • 2015-11-10
      • 2014-09-12
      相关资源
      最近更新 更多