【问题标题】:AES encryption/decryptionAES加密/解密
【发布时间】:2012-02-24 01:40:33
【问题描述】:

下面是一些适用于字符串的代码:

Public Function AESEncrypt(ByVal PlainText As String, ByVal Password As String, ByVal salt As String)
    Dim HashAlgorithm As String = "SHA1" 'Can be SHA1 or MD5
    Dim PasswordIterations As String = 2
    Dim InitialVector As String = "CanEncryption123" 'This should be a string of 16 ASCII characters.
    Dim KeySize As Integer = 256 'Can be 128, 192, or 256.

    If (String.IsNullOrEmpty(PlainText)) Then
        Return ""
        Exit Function
    End If
    Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector)
    Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt)
    Dim PlainTextBytes As Byte() = Encoding.UTF8.GetBytes(PlainText)
    Dim DerivedPassword As PasswordDeriveBytes = New PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations)
    Dim KeyBytes As Byte() = DerivedPassword.GetBytes(KeySize / 8)
    Dim SymmetricKey As RijndaelManaged = New RijndaelManaged()
    SymmetricKey.Mode = CipherMode.CBC

    Dim CipherTextBytes As Byte() = Nothing
    Using Encryptor As ICryptoTransform = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes)
        Using MemStream As New MemoryStream()
            Using CryptoStream As New CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write)
                CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length)
                CryptoStream.FlushFinalBlock()
                CipherTextBytes = MemStream.ToArray()
                MemStream.Close()
                CryptoStream.Close()
            End Using
        End Using
    End Using
    SymmetricKey.Clear()
    Return Convert.ToBase64String(CipherTextBytes)
End Function
Public Function AESDecrypt(ByVal CipherText As String, ByVal password As String, ByVal salt As String) As String
    Dim HashAlgorithm As String = "SHA1"
    Dim PasswordIterations As String = 2
    Dim InitialVector As String = "CanEncryption123"
    Dim KeySize As Integer = 256

    If (String.IsNullOrEmpty(CipherText)) Then
        Return ""
    End If
    Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector)
    Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt)
    Dim CipherTextBytes As Byte() = Convert.FromBase64String(CipherText)
    Dim DerivedPassword As PasswordDeriveBytes = New PasswordDeriveBytes(password, SaltValueBytes, HashAlgorithm, PasswordIterations)
    Dim KeyBytes As Byte() = DerivedPassword.GetBytes(KeySize / 8)
    Dim SymmetricKey As RijndaelManaged = New RijndaelManaged()
    SymmetricKey.Mode = CipherMode.CBC
    Dim PlainTextBytes As Byte() = New Byte(CipherTextBytes.Length - 1) {}

    Dim ByteCount As Integer = 0

    Using Decryptor As ICryptoTransform = SymmetricKey.CreateDecryptor(KeyBytes, InitialVectorBytes)
        Using MemStream As MemoryStream = New MemoryStream(CipherTextBytes)
            Using CryptoStream As CryptoStream = New CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read)
                ByteCount = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length)
                MemStream.Close()
                CryptoStream.Close()
            End Using
        End Using
    End Using
    SymmetricKey.Clear()
    Return Encoding.UTF8.GetString(PlainTextBytes, 0, ByteCount)
End Function

我可以在修改这些函数以加密/解密字节数组而不是字符串方面提供一些帮助吗?此外,要让函数返回加密/解密的字节数组,而不是字符串。

谢谢

【问题讨论】:

    标签: vb.net encryption aes


    【解决方案1】:
    Public Function AESEncrypt(ByVal PlainBytes As Byte, ByVal Password As String, ByVal salt As String)
    Dim HashAlgorithm As String = "SHA1" 'Can be SHA1 or MD5
    Dim PasswordIterations As String = 2
    Dim InitialVector As String = "CanEncryption123" 'This should be a string of 16 ASCII characters.
    Dim KeySize As Integer = 256 'Can be 128, 192, or 256.
    
    Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector)
    Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt)
    Dim DerivedPassword As PasswordDeriveBytes = New PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations)
    Dim KeyBytes As Byte() = DerivedPassword.GetBytes(KeySize / 8)
    Dim SymmetricKey As RijndaelManaged = New RijndaelManaged()
    SymmetricKey.Mode = CipherMode.CBC
    
    Dim CipherTextBytes As Byte() = Nothing
    Using Encryptor As ICryptoTransform = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes)
        Using MemStream As New MemoryStream()
            Using CryptoStream As New CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write)
                CryptoStream.Write(PlainBytes, 0, PlainBytes.Length)
                CryptoStream.FlushFinalBlock()
                CipherTextBytes = MemStream.ToArray()
                MemStream.Close()
                CryptoStream.Close()
            End Using
        End Using
    End Using
    SymmetricKey.Clear()
    Return Convert.ToBase64String(CipherTextBytes)
    End Function
    Public Function AESDecrypt(ByVal CipherBytes As Byte, ByVal password As String, ByVal salt As String) As String
    Dim HashAlgorithm As String = "SHA1"
    Dim PasswordIterations As String = 2
    Dim InitialVector As String = "CanEncryption123"
    Dim KeySize As Integer = 256
    
    If (String.IsNullOrEmpty(CipherText)) Then
        Return ""
    End If
    Dim InitialVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitialVector)
    Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(salt)
    Dim DerivedPassword As PasswordDeriveBytes = New PasswordDeriveBytes(password, SaltValueBytes, HashAlgorithm, PasswordIterations)
    Dim KeyBytes As Byte() = DerivedPassword.GetBytes(KeySize / 8)
    Dim SymmetricKey As RijndaelManaged = New RijndaelManaged()
    SymmetricKey.Mode = CipherMode.CBC
    Dim PlainTextBytes As Byte() = New Byte(CipherBytes.Length - 1) {}
    
    Dim ByteCount As Integer = 0
    
    Using Decryptor As ICryptoTransform = SymmetricKey.CreateDecryptor(KeyBytes, InitialVectorBytes)
        Using MemStream As MemoryStream = New MemoryStream(CipherBytes)
            Using CryptoStream As CryptoStream = New CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read)
                ByteCount = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length)
                MemStream.Close()
                CryptoStream.Close()
            End Using
        End Using
    End Using
    SymmetricKey.Clear()
    Return Encoding.UTF8.GetString(PlainTextBytes, 0, ByteCount)
    End Function
    

    您使用的代码实际上将输入字符串转换为字节数组。此代码接受字节数组。

    【讨论】:

      【解决方案2】:

      我将这个(在 Google 上找到)用于字符串 AES 加密/解密:

      Imports System.Security.Cryptography
      
      Namespace TextCrypters
      
          Public Class AESCrypter
      
              Public Shared pass As String = "password"
      
              Public Shared Function AES_Encrypt(ByVal input As String) As String
                  Dim AES As New System.Security.Cryptography.RijndaelManaged
                  Dim Hash_AES As New System.Security.Cryptography.MD5CryptoServiceProvider
                  Dim encrypted As String = ""
                  Try
                      Dim hash(31) As Byte
                      Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
                      Array.Copy(temp, 0, hash, 0, 16)
                      Array.Copy(temp, 0, hash, 15, 16)
                      AES.Key = hash
                      AES.Mode = CipherMode.ECB
                      Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
                      Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(input)
                      encrypted = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
                      Return encrypted
                  Catch ex As Exception
                      Return Nothing
                  End Try
      
              End Function
      
              Public Shared Function AES_Decrypt(ByVal input As String) As String
                  Dim AES As New System.Security.Cryptography.RijndaelManaged
                  Dim Hash_AES As New System.Security.Cryptography.MD5CryptoServiceProvider
                  Dim decrypted As String = ""
                  Try
                      Dim hash(31) As Byte
                      Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
                      Array.Copy(temp, 0, hash, 0, 16)
                      Array.Copy(temp, 0, hash, 15, 16)
                      AES.Key = hash
                      AES.Mode = CipherMode.ECB
                      Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateDecryptor
                      Dim Buffer As Byte() = Convert.FromBase64String(input)
                      decrypted = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
                      Return decrypted
                  Catch ex As Exception
                      Return Nothing
                  End Try
      
              End Function
      
          End Class
      
      End Namespace
      

      要使用它,只需这样做:

      Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
          TextBox2.Text = AESCrypter.AES_Encrypt(TextBox1.Text)
      End Sub
      
      Protected Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
          TextBox4.Text = AESCrypter.AES_Decrypt(TextBox3.Text)
      End Sub
      

      【讨论】:

      • 该代码可能“工作”,但它肯定不安全(ECB 模式),它会破坏任何包含非 ASCII 字符的输入。
      【解决方案3】:

      只需将新函数中的所有内容从Dim ByteCount As Integer = 0 复制到SymmetricKey.Clear() 即可删除所有字符串?之后你只需要定义函数的参数。

      【讨论】:

      • 字节数组的加密函数怎么样。 :)
      【解决方案4】:

      最简单的方法是使用包装函数,将字节数组转换为字符串,使用AESEncrypt 函数对其进行加密,然后将字符串转换回字节数组。你可以找到VB.net的转换函数here

      编辑添加:我想我弄错了。似乎 VB String 是 Unicode 格式,这些翻译函数将其转换为/从 UTF8 字节数组。这不是我们所需要的……

      【讨论】:

      • 这种方法是否与修改函数以接受字节数组而不是字符串一样有效/有效?
      • 同样高效?不,但我认为开销不会很大。一样有效?是的。
      • 我已经使用转换函数将字节数组转换为字符串,反之亦然。出于某种原因,如果我尝试(从文件中)解密一个加密的字节数组,它与原始文件不同。使用这些转换例程有什么限制吗?
      • 另外,有些文件不能工作。我收到此错误:“输入不是有效的 Base-64 字符串,因为它包含非 base 64 字符、两个以上的填充字符或填充字符中的非空白字符。”
      猜你喜欢
      • 2016-09-22
      • 2015-01-20
      • 2014-01-05
      • 2019-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多