我在Visual Basic中遇到AES加密问题。这个PHP代码实现了我想要的,但是我试图编写的可视化基本代码总是失败,并显示有关错误初始化向量的消息。
<?php
function decrypt($data) {
$value = "";
$value = base64_decode($data);
$ivlength = 8;
$iv = substr($value,0, $ivlength);
$value = substr($value,$ivlength,strlen($value)-$ivlength);
$key = 'MyKeygoeshere12345678901'; //Muss wegen der verschlüsselung genau 24 zeichen lang sein.
return preg_replace('/[^A-Za-z0-9öäüÄÖÜ\ \:]/', '',decryptAES($value,$iv,$key));
}
function decryptAES($content,$iv, $key) {
// Setzt den Verschlüsselungsalgorithmus
$cp = mcrypt_module_open('tripledes', '', 'cbc', '');
// Ermittelt die Anzahl der Bits, welche die Schlüssellänge des Keys festlegen
$ks = mcrypt_enc_get_key_size($cp);
// Erstellt den Schlüssel, der für die Verschlüsselung genutzt wird
$key = substr($key, 0, $ks);
// Initialisiert die Verschlüsselung
mcrypt_generic_init($cp, $key, $iv);
// Entschlüsselt die Daten
$decrypted = mdecrypt_generic($cp, $content);
// Beendet die Verschlüsselung
mcrypt_generic_deinit($cp);
// Schließt das Modul
mcrypt_module_close($cp);
return trim($decrypted);
}
?>
那就是Visual Basic代码:
Option Explicit On
Option Strict On
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Module AES
Public initv() As Byte
Public Function Encrypt(ByVal strData As String) As String
Try
Dim rd As New TripleDESCryptoServiceProvider
Dim strKey As String = "MyKeygoeshere12345678901"
Dim key() As Byte = Encoding.Default.GetBytes(strKey)
rd.Key = key
rd.GenerateIV()
Dim iv() As Byte = rd.IV
initv = rd.IV
Dim ms As New MemoryStream
ms.Write(iv, 0, iv.Length)
Dim cs As New CryptoStream(ms, rd.CreateEncryptor, CryptoStreamMode.Write)
Dim data() As Byte = System.Text.Encoding.Default.GetBytes(strData)
cs.Write(data, 0, data.Length)
cs.FlushFinalBlock()
Dim encdata() As Byte = ms.ToArray()
Encrypt = Convert.ToBase64String(encdata)
cs.Close()
rd.Clear()
Catch err As Exception
Encrypt = err.Message
End Try
End Function
Public Function Decrypt(ByVal data As String) As String
Dim aes As New AesCryptoServiceProvider()
Dim crypted As String = Base64.FromBase64(data)
Dim strKey As String = "MyKeygoeshere12345678901"
Dim key() As Byte = Encoding.Default.GetBytes(strKey)
aes.Padding = PaddingMode.Zeros
aes.Mode = CipherMode.CBC
aes.KeySize = 192
aes.Key = key
Dim IV As String = crypted.Substring(0, 8)
Dim ivby() As Byte = Encoding.UTF8.GetBytes(IV)
Dim tmp As Integer = 0
IV = crypted.Substring(0, 16)
ivby = Encoding.UTF8.GetBytes(IV)
MsgBox(aes.BlockSize)
aes.IV = ivby
Dim src As Byte() = Encoding.Default.GetBytes(crypted.Substring(8, crypted.Length() - 8))
Using dec As ICryptoTransform = aes.CreateDecryptor()
Dim dest As Byte() = dec.TransformFinalBlock(src, 0, src.Length)
Return Encoding.Unicode.GetString(dest)
End Using
End Function
End Module
您能否告诉我上面的解密代码有什么问题?
答案 0 :(得分:2)
首先,IV由 bytes 组成,而不是字符,所以你不应该使用字符串函数。此外,IV总是与CBC模式加密中底层密码的块大小相同。由于AES的块大小为16字节而不是8,因此应将其替换为16,或者使用aes.BlockSize / 8
替换它。
答案 1 :(得分:2)
为了您的方便,使用Triple DES(我的系统似乎不包含AES,您的PHP代码使用三重DES。
Option Explicit On
Option Strict On
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Module TDES
Public initv() As Byte
Public Function Encrypt(ByVal strData As String) As String
Try
Dim rd As New TripleDESCryptoServiceProvider
Dim strKey As String = "MyKeygoeshere12345678901"
Dim key() As Byte = Encoding.UTF8.GetBytes(strKey)
rd.Key = key
rd.GenerateIV()
Dim iv() As Byte = rd.IV
initv = rd.IV
Dim ms As New MemoryStream
ms.Write(iv, 0, iv.Length)
Dim cs As New CryptoStream(ms, rd.CreateEncryptor, CryptoStreamMode.Write)
Dim data() As Byte = System.Text.Encoding.UTF8.GetBytes(strData)
cs.Write(data, 0, data.Length)
cs.FlushFinalBlock()
Dim encdata() As Byte = ms.ToArray()
Encrypt = Convert.ToBase64String(encdata)
cs.Close()
rd.Clear()
Catch err As Exception
Encrypt = err.Message
End Try
End Function
Public Function Decrypt(ByVal data As String) As String
Dim aes As New TripleDESCryptoServiceProvider()
Dim crypted() As Byte = Convert.FromBase64String(data)
Dim strKey As String = "MyKeygoeshere12345678901"
Dim key() As Byte = Encoding.UTF8.GetBytes(strKey)
aes.Padding = PaddingMode.Zeros
aes.Mode = CipherMode.CBC
aes.KeySize = 192
aes.Key = key
Dim ivSize As Integer = aes.BlockSize / 8
Dim IV(ivSize - 1) As Byte
Array.Copy(crypted, 0, IV, 0, ivSize)
aes.IV = IV
Dim src(crypted.Length - ivSize - 1) As Byte
Array.Copy(crypted, ivSize, src, 0, src.Length)
Using dec As ICryptoTransform = aes.CreateDecryptor()
Dim dest As Byte() = dec.TransformFinalBlock(src, 0, src.Length)
Return Encoding.UTF8.GetString(dest)
End Using
End Function
End Module
请注意,您应该能够将TripleDESCryptoServiceProvider
替换为AesCryptoServiceProvider
。另请注意,这使用base 64编码密文,因此您应该在PHP代码中使用Base 64编码。