VBA AES CBC加密

问题描述

我在https://github.com/susam/aes.vbs中提到了加密,下面是我最终得到的代码

Function Min(a,b)
    Min = a
    If b < a Then Min = b
End Function

Function B64Encode(bytes)
    Dim result As String
    Dim b64Block() As Byte
    Dim b64Enc As Object
    Dim utf8 As Object
    Dim Offset,Length,BlockSize As Integer
    
    Set b64Enc = CreateObject("System.Security.Cryptography.ToBase64Transform")
    Set utf8 = CreateObject("System.Text.UTF8Encoding")
    BlockSize = b64Enc.InputBlockSize
    For Offset = 0 To LenB(bytes) - 1 Step BlockSize
        Length = Min(BlockSize,UBound(bytes) - Offset)
        b64Block = b64Enc.TransformFinalBlock((bytes),Offset,Length)
        result = result & utf8.GetString((b64Block))
    Next
    B64Encode = result
End Function

Function B64Decode(b64Str)
    Dim utf8 As Object
    Dim bytes() As Byte
    Dim b64Dec As Object
    
    Set utf8 = CreateObject("System.Text.UTF8Encoding")
    Set b64Dec = CreateObject("System.Security.Cryptography.FromBase64Transform")
    bytes = utf8.GetBytes_4(b64Str)
    B64Decode = b64Dec.TransformFinalBlock((bytes),UBound(bytes))
End Function

Function Encrypt(plaintext,aesKey)
    Dim cipherBytes,aesKeyBytes,ivKeyBytes,plainBytes() As Byte
    
    Dim utf8,AES,aesEnc As Object
    Dim aesIV() As Byte
    Set AES = CreateObject("System.Security.Cryptography.RijndaelManaged")
    Set utf8 = CreateObject("System.Text.UTF8Encoding")
    'Set cipherMode = Getobject("System.Security.Cryptography.CipherMode")
    AES.KeySize = 256
    AES.Mode = 1
    AES.Key = CreateObject("System.Text.UTF8Encoding").GetBytes_4("V$ry300DP3r$0NM3")
    AES.IV = CreateObject("System.Text.UTF8Encoding").GetBytes_4("HR$2pIjHR$2pIjPa")
    plainBytes = utf8.GetBytes_4(plaintext)
    'Set aesEnc = AES.CreateEncryptor_2((aesKeyBytes),(ivKeyBytes))
    cipherBytes = AES.TransformFinalBlock((plainBytes),UBound(plainBytes))
        
    Encrypt = B64Encode(cipherBytes)
End Function

现在上面的代码告诉我“指定的初始化向量(iv)与该算法的块大小不匹配”

我们不能设置IV动态吗?

解决方法

Function Min(a,b)
    Min = a
    If b < a Then Min = b
End Function

Function B64Encode(bytes)
    Dim result As String
    Dim b64Block() As Byte
    Dim b64Enc As Object
    Dim utf8 As Object
    Dim Offset,Length,BlockSize As Integer
    
    Set b64Enc = CreateObject("System.Security.Cryptography.ToBase64Transform")
    Set utf8 = CreateObject("System.Text.UTF8Encoding")
    BlockSize = b64Enc.InputBlockSize
    For Offset = 0 To LenB(bytes) - 1 Step BlockSize
        Length = Min(BlockSize,UBound(bytes) - Offset)
        b64Block = b64Enc.TransformFinalBlock((bytes),Offset,Length)
        result = result & utf8.GetString((b64Block))
    Next
    B64Encode = result
End Function

Function B64Decode(b64Str)
    Dim utf8 As Object
    Dim bytes() As Byte
    Dim b64Dec As Object
    
    Set utf8 = CreateObject("System.Text.UTF8Encoding")
    Set b64Dec = CreateObject("System.Security.Cryptography.FromBase64Transform")
    bytes = utf8.GetBytes_4(b64Str)
    B64Decode = b64Dec.TransformFinalBlock((bytes),UBound(bytes))
End Function


Function Encrypt(plaintext,aesKey)
    Dim cipherBytes,aesKeyBytes,ivKeyBytes,plainBytes() As Byte
    
    Dim utf8,AES,aesEnc,cipherMode As Object
    Dim aesIV() As Byte
        
    Set AES = CreateObject("System.Security.Cryptography.RijndaelManaged")
    Set utf8 = CreateObject("System.Text.UTF8Encoding")
    'Set cipherMode = CreateObject("System.Security.Cryptography.CipherMode")
    
    AES.KeySize = 256
    AES.BlockSize = 256
    'CipherMode.CBC
    AES.Mode = 1
    'PaddingMode.PKCS7
    AES.Padding = 2
    AES.Key = CreateObject("System.Text.UTF8Encoding").GetBytes_4("ThirtyTwoBytes3$ThirtyTwoBytes3$")
    AES.IV = CreateObject("System.Text.UTF8Encoding").GetBytes_4("3$ThreeTwoBytes3$ThreeTwoBytes3$")
    'plainBytes = utf8.GetBytes_4(plaintext)
    plainBytes = B64Decode(plaintext)
    'Set aesEnc = AES.CreateEncryptor_2((aesKeyBytes),(ivKeyBytes))
    cipherBytes = AES.CreateEncryptor().TransformFinalBlock((plainBytes),UBound(plainBytes))
        
    Encrypt = B64Encode(cipherBytes)
End Function

Sub encrypt_hell()
Debug.Print Encrypt("Hello","PattamuthuArumug")
End Sub

我正在使用256位AES CBC,因此必须使用32个字节的密钥和IV