0

我对 Visual basic 中的 AES 加密有疑问。这个 PHP 代码可以满足我的要求,但我尝试编写的 Visual Basic 代码总是失败,并显示有关错误初始化向量的消息。

<?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

你能告诉我上面的解密代码有什么问题吗?

4

2 回答 2

2

首先,IV 由字节而不是字符组成,因此您不应在其上使用字符串函数。此外,IV 的大小始终与 CBC 模式加密中基础密码的块大小相同。由于 AES 的块大小是 16 个字节,而不是 8 个字节,因此您应该将其替换为 16,或者在您的情况下使用aes.BlockSize / 8.

于 2013-09-22T16:49:41.830 回答
2

为了您的方便,使用三重 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

请注意,您应该能够替换TripleDESCryptoServiceProviderAesCryptoServiceProvider. 另请注意,这使用 base 64 编码的密文,因此您应该在 PHP 代码中同样使用 Base 64 编码。

于 2013-09-22T19:23:44.950 回答