dora12345678 2017-01-09 13:21
浏览 434


I want to decrypt in strings encrypted in PHP via openssl_encrypt function:

$encrypted_string = openssl_encrypt(

I tried with this class:

Public Class Aes256Encrypter
    Public Function Encrypt(ByVal plainText As String, ByVal secretKey As String) As Byte()
        Dim encryptedPassword As Byte()
        Using outputStream As MemoryStream = New MemoryStream()
            Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
            Using cryptoStream As CryptoStream = New CryptoStream(outputStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write)
                Dim inputBuffer() As Byte = Encoding.Unicode.GetBytes(plainText)
                cryptoStream.Write(inputBuffer, 0, inputBuffer.Length)
                encryptedPassword = outputStream.ToArray()
            End Using
        End Using
        Return encryptedPassword
    End Function

    Public Function Decrypt(ByVal encryptedBytes As Byte(), ByVal secretKey As String) As String
        Dim plainText As String = Nothing
        Using inputStream As MemoryStream = New MemoryStream(encryptedBytes)
            Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
            Using cryptoStream As CryptoStream = New    CryptoStream(inputStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read)
                Dim outputBuffer(0 To CType(inputStream.Length - 1, Integer)) As Byte
                Dim readBytes As Integer = cryptoStream.Read(outputBuffer, 0, CType(inputStream.Length, Integer))
                plainText = Encoding.Unicode.GetString(outputBuffer, 0, readBytes)
            End Using
        End Using
        Return plainText
    End Function

    Private Function getAlgorithm(ByVal secretKey As String) As RijndaelManaged
        Const salt As String = "put your salt here"
        Const keySize As Integer = 256

        Dim keyBuilder As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(secretKey, Encoding.Unicode.GetBytes(salt))
        Dim algorithm As RijndaelManaged = New RijndaelManaged()
        algorithm.KeySize = keySize
        algorithm.IV = keyBuilder.GetBytes(CType(algorithm.BlockSize / 8, Integer))
        algorithm.Key = keyBuilder.GetBytes(CType(algorithm.KeySize / 8, Integer))
        algorithm.Padding = PaddingMode.PKCS7
        Return algorithm
    End Function
End Class

I use IV "initialization_vector" as salt string, but at runtime an error is thrown: 'System.Security.Cryptography.CryptographicException' in mscorlib.dll. An error occurred: Padding is invalid and cannot be removed.

Where am I doing wrong?

  • 写回答

1条回答 默认 最新

  • doushi7394 2017-01-12 02:35

    Okay, so this is a C# answer, and I don't like it; but I've produced a thing which gives the same answer as php's openssl_encrypt.

    • PHP passes the string as if it were bytes, so Encoding.ASCII (not sure what it does with non-ASCII data, actually)
    • PHP/OpenSSL silently truncates long keys (so your 60 character password is a 32 character password)
    • Working with the same data in ASCII strings and hex bytes is a pain in the rear.


    private static byte[] php_encode(string php_string, int expectedLength)
        byte[] temp = Encoding.ASCII.GetBytes(php_string);
        if (temp.Length == expectedLength)
            return temp;
        byte[] ret = new byte[expectedLength];
        Buffer.BlockCopy(temp, 0, ret, 0, Math.Min(temp.Length, expectedLength));
        return ret;
    private static string php_encrypt_aes256(string php_data, string php_password, string php_iv)
        byte[] key = php_encode(php_password, 32);
        byte[] iv = php_encode(php_iv, 16);
        byte[] data = Encoding.ASCII.GetBytes(php_data);
        using (Aes aes = Aes.Create())
        using (ICryptoTransform encryptor = aes.CreateEncryptor(key, iv))
            return Convert.ToBase64String(encryptor.TransformFinalBlock(data, 0, data.Length));

    Test inputs:


    $ /usr/bin/php -r "print(openssl_encrypt('potato', 'AES256', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 0, '0123456789ABCDEF') . \"
    $ /usr/bin/php -r "print(openssl_encrypt('potato', 'AES256', '0123456789abcdefghijklmnopqrstuv', 0, '0123456789ABCDEF') . \"
    $ /usr/bin/php -r "print(openssl_encrypt('potato', 'AES256', '0123456789abcdefghijklmnopqrstu', 0, '0123456789ABCDEF') . \"
    $ /usr/bin/php -r "print(openssl_encrypt('potato', 'AES256', '0123456789abcdefghijklmnopqrstuv', 0, '0123456789ABCDE') . \"
    PHP Warning:  openssl_encrypt(): IV passed is only 15 bytes long, cipher expects an IV of precisely 16 bytes, padding with \0 in Command line code on line 1

    openssl enc

    $ openssl enc -aes-256-cbc -K 303132333435363738396162636465666768696a6b6c6d6e6f70717273747576 -in -a -iv 30313233343536373839414243444546
    $ openssl enc -aes-256-cbc -K 303132333435363738396162636465666768696a6b6c6d6e6f70717273747500 -in -a -iv 30313233343536373839414243444546
    $ openssl enc -aes-256-cbc -K 303132333435363738396162636465666768696a6b6c6d6e6f70717273747576 -in -a -iv 30313233343536373839414243444500

    My code

    Console.WriteLine(php_encrypt_aes256("potato", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "0123456789ABCDEF"));
    Console.WriteLine(php_encrypt_aes256("potato", "0123456789abcdefghijklmnopqrstuv", "0123456789ABCDEF"));
    Console.WriteLine(php_encrypt_aes256("potato", "0123456789abcdefghijklmnopqrstu", "0123456789ABCDEF"));
    Console.WriteLine(php_encrypt_aes256("potato", "0123456789abcdefghijklmnopqrstuv", "0123456789ABCDE"));


    本回答被题主选为最佳回答 , 对您是否有帮助呢?



    • ¥15 Unity微信小游戏上调用ReadPixels()方法报错
    • ¥15 如何通过求后验分布求得样本中属于两种物种其中一种的概率?
    • ¥15 q从常量变成sin函数,怎么改写python代码?
    • ¥15 图论编程问题,有可以指导的吗
    • ¥15 DEA的CCR模型画图
    • ¥15 请假各位一个关于安卓车机的问题
    • ¥15 光谱仪怎么看这样的透射谱
    • ¥15 pyqt5 如何实现输入框输入关键词,下拉框显示模糊查询返回的结果?
    • ¥20 fluent模拟,可以燃烧和相变同时模拟吗?
    • ¥50 海康摄像头,C#如何识别车牌号码和抓取JPG