在VB.NET中使用AesCryptoServiceProvider

3

我的问题实际上比如何在VB.NET中使用AES更加复杂,因为我真正想做的是在JACOB跨越Java应用程序中使用VB.NET中的AES。但现在,我需要关注的是AES本身的实现。

以下是我的加密代码:

Public Function EncryptAES(ByVal toEncrypt As String, ByVal key As String) As Byte()
    Dim keyArray = Convert.FromBase64String(key)
    Dim toEncryptArray = Encoding.Unicode.GetBytes(toEncrypt)

    Dim aes = New AesCryptoServiceProvider
    aes.Key = keyArray
    aes.Mode = CipherMode.ECB
    aes.Padding = PaddingMode.ISO10126
    Dim encryptor = aes.CreateEncryptor()

    Dim encrypted = encryptor.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length)
    aes.Clear()

    Return encrypted
End Function

回到Java代码后,我将字节数组转换为十六进制字符串。

现在,为了反向处理,这是我的解密代码。

Public Function DecryptAES(ByVal toDecrypt As String, ByVal key As String) As Byte()
    Dim keyArray = Convert.FromBase64String(key)
    Dim toDecryptArray = Convert.FromBase64String(toDecrypt)

    Dim aes = New AesCryptoServiceProvider
    aes.Key = keyArray
    aes.Mode = CipherMode.ECB
    aes.Padding = PaddingMode.ISO10126
    Dim decryptor = aes.CreateDecryptor()

    Dim decrypted = decryptor.TransformFinalBlock(toDecryptArray, 0, toDecryptArray.Length)
    aes.Clear()
    Return decrypted
End Function

当我运行解密代码时,出现以下错误信息:

填充无效,无法移除。


你是否尝试将加密数据保存在某个地方,然后将该保存的数据逐字节与通过Java传递后解密函数的调用进行比较? - Joel Coehoorn
Visual Studio 2008 Pro我无法进行您建议的测试,因为我无法获得从解密中返回以进行测试的返回值。错误是由我的VB解密函数引发的。 - Collegeman
你能在不将数据发送到Java的情况下进行往返传输吗?即 DecryptAES(EncryptAES(“text”,“key”),“key”) - Jeremy Wiebe
没问题,Jeremy。实际上,我已经改进了代码。我很快就会发布一个解决方案。 - Collegeman
1
请注意,ECB模式很少是一个好的选择。因此,如果您想在VB.net中加密某些内容,请不要复制粘贴此代码。 - CodesInChaos
显示剩余2条评论
1个回答

0

好的,我的原始代码有几个问题。

首先,没有调试。我必须添加一个内部测试来验证我的代码在包装成Java之前是否可以加密和解密。这是我犯的愚蠢错误。

其次:加密器和解密器对象的TransformFinalBlock方法似乎不像广告中所说的那样执行。

够了废话,这是代码

Public Function EncryptAES(ByVal clearText As String, ByVal key As String) As String

    ' prepare input
    Dim keyBytes = Convert.FromBase64String(key)
    Dim sourceBytes = Encoding.Unicode.GetBytes(clearText)

    ' prepare encryption provider
    Dim aes = New AesCryptoServiceProvider
    aes.Key = keyBytes
    aes.Mode = CipherMode.ECB
    aes.Padding = PaddingMode.ISO10126
    Dim encryptor = aes.CreateEncryptor()

    Dim ms = New MemoryStream
    Dim cs = New CryptoStream(ms, encryptor, CryptoStreamMode.Write)
    cs.Write(sourceBytes, 0, sourceBytes.Length)
    cs.FlushFinalBlock()
    Dim encrypted = Convert.ToBase64String(ms.ToArray())

    'Dim decrypted = DecryptAES(encrypted, key)
    'If Not EventLog.SourceExists("CryptoBridge") Then
    '   EventLog.CreateEventSource("CryptoBridge", "CryptoBridge")
    'End If
    'Dim log As New EventLog
    'log.Source = "CryptoBridge"
    'log.WriteEntry(clearText & ":" & decrypted)

    aes.Clear()
    cs.Dispose()
    ms.Dispose()

    Return encrypted
End Function

Public Function DecryptAES(ByVal base64Cipher As String, ByVal key As String) As String
    Dim keyBytes = Convert.FromBase64String(key)
    Dim cipherBytes = Convert.FromBase64String(base64Cipher)

    ' prepare decryption provider
    Dim aes = New AesCryptoServiceProvider
    aes.Key = keyBytes
    aes.Mode = CipherMode.ECB
    aes.Padding = PaddingMode.ISO10126
    Dim decryptor = aes.CreateDecryptor()

    Dim ms = New MemoryStream(cipherBytes)
    Dim cs = New CryptoStream(ms, decryptor, CryptoStreamMode.Read)

    Dim decryptedBytes As Byte()
    ReDim decryptedBytes(cipherBytes.Length)

    Dim readByteCount = cs.Read(decryptedBytes, 0, decryptedBytes.Length)
    Dim decrypted = Encoding.Unicode.GetString(decryptedBytes, 0, readByteCount)

    aes.Clear()
    cs.Dispose()
    ms.Dispose()

    Return decrypted
End Function

接下来,我将修改这段代码,将AES算法提升到256位和CBC密码模式,这需要一个初始向量(IV)值。这增加了实现的复杂性,直到其余部分100%工作正常之前,我还没有准备好添加它。
感谢所有评论我的问题的人。

好奇 - 为什么你不直接使用Java内置的AES密码,而要跨越JACOB呢? - Cheeso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接