我想通过openssl_encrypt函数解密用PHP加密的VB.net字符串:
$encrypted_string = openssl_encrypt(
$string,
'AES256',
'secret_password',
0,
'initialization_vector'
);
我尝试了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)
cryptoStream.FlushFinalBlock()
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
我使用IV" initialization_vector"作为salt字符串,但在运行时会抛出错误:' System.Security.Cryptography.CryptographicException'在mscorlib.dll中。发生错误:填充无效,无法删除。
我在哪里做错了?
答案 0 :(得分:3)
好的,这是一个C#答案,我不喜欢它;但我已经制作了一个与php openssl_encrypt
给出相同答案的东西。
Encoding.ASCII
(实际上不确定它对非ASCII数据的作用)代码:
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));
}
}
$ /usr/bin/php -r "print(openssl_encrypt('potato', 'AES256', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 0, '0123456789ABCDEF') . \"\n\");"
wiZGvfABfairN4gKcnqD2Q==
$ /usr/bin/php -r "print(openssl_encrypt('potato', 'AES256', '0123456789abcdefghijklmnopqrstuv', 0, '0123456789ABCDEF') . \"\n\");"
wiZGvfABfairN4gKcnqD2Q==
$ /usr/bin/php -r "print(openssl_encrypt('potato', 'AES256', '0123456789abcdefghijklmnopqrstu', 0, '0123456789ABCDEF') . \"\n\");"
XUkYwaomkIXYstlOQlNoBQ==
$ /usr/bin/php -r "print(openssl_encrypt('potato', 'AES256', '0123456789abcdefghijklmnopqrstuv', 0, '0123456789ABCDE') . \"\n\");"
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
ah+yXvQEocgLNES2nh2kXA==
$ openssl enc -aes-256-cbc -K 303132333435363738396162636465666768696a6b6c6d6e6f70717273747576 -in enc.data -a -iv 30313233343536373839414243444546
wiZGvfABfairN4gKcnqD2Q==
$ openssl enc -aes-256-cbc -K 303132333435363738396162636465666768696a6b6c6d6e6f70717273747500 -in enc.data -a -iv 30313233343536373839414243444546
XUkYwaomkIXYstlOQlNoBQ==
$ openssl enc -aes-256-cbc -K 303132333435363738396162636465666768696a6b6c6d6e6f70717273747576 -in enc.data -a -iv 30313233343536373839414243444500
ah+yXvQEocgLNES2nh2kXA==
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"));
输出:
wiZGvfABfairN4gKcnqD2Q==
wiZGvfABfairN4gKcnqD2Q==
XUkYwaomkIXYstlOQlNoBQ==
ah+yXvQEocgLNES2nh2kXA==
答案 1 :(得分:0)
我做了一点修改,但是如果有人需要,我可以在VB.net中进行解密。
Private Shared Function php_decrypt_aes256(ByVal php_password As String, ByVal php_iv As String, ByVal php_data As String) As String
Dim key As Byte() = php_encode(php_password, 32)
Dim iv As Byte() = php_encode(php_iv, 16)
Dim buff As Byte() = Encoding.ASCII.GetBytes(php_data)
Using aes As Aes = Aes.Create()
Using decryptor As ICryptoTransform = aes.CreateDecryptor(key, iv)
buff = Convert.FromBase64String(php_data)
Return ASCIIEncoding.ASCII.GetString(decryptor.TransformFinalBlock(buff, 0, buff.Length))
End Using
End Using
End Function