5

是否有用于 VB.NET 的 AES 加密的标准库?我想用静态私钥加密一个字符串。

我用谷歌搜索并发现了很多变化。我真的不知道如何确定哪些算法是安全的。

4

2 回答 2

9

System.Security.Cryptography命名空间包含执行大多数标准加密任务所需的所有类。不幸的是,由于加密是一个相当复杂的主题,因此这些课程有些难以使用——尤其是对于初学者。有时很难找到一个简单的工作示例来开始。但是,由于我很好,我将为您提供一个简单的示例,您可以使用和改进:)

您可能要使用的类称为RijndaelManaged. 那是实现典型 AES 加密的类。这是一个示例类,它使用它在纯文本字符串和字节数组之间进行转换:

Public Class Aes256Encrypter
    Public Function Encrypt(ByVal plainText As String, ByVal secretKey As String) As Byte()
        Dim encryptedPassword As Byte()
        Using outputStream As MemoryStream = New MemoryStream()
            Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
            Using cryptoStream As CryptoStream = New CryptoStream(outputStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write)
                Dim inputBuffer() As Byte = Encoding.Unicode.GetBytes(plainText)
                cryptoStream.Write(inputBuffer, 0, inputBuffer.Length)
                cryptoStream.FlushFinalBlock()
                encryptedPassword = outputStream.ToArray()
            End Using
        End Using
        Return encryptedPassword
    End Function

    Public Function Decrypt(ByVal encryptedBytes As Byte(), ByVal secretKey As String) As String
        Dim plainText As String = Nothing
        Using inputStream As MemoryStream = New MemoryStream(encryptedBytes)
            Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
            Using cryptoStream As CryptoStream = New CryptoStream(inputStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read)
                Dim outputBuffer(0 To CType(inputStream.Length - 1, Integer)) As Byte
                Dim readBytes As Integer = cryptoStream.Read(outputBuffer, 0, CType(inputStream.Length, Integer))
                plainText = Encoding.Unicode.GetString(outputBuffer, 0, readBytes)
            End Using
        End Using
        Return plainText
    End Function

    Private Function getAlgorithm(ByVal secretKey As String) As RijndaelManaged
        Const salt As String = "put your salt here"
        Const keySize As Integer = 256

        Dim keyBuilder As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(secretKey, Encoding.Unicode.GetBytes(salt))
        Dim algorithm As RijndaelManaged = New RijndaelManaged()
        algorithm.KeySize = keySize
        algorithm.IV = keyBuilder.GetBytes(CType(algorithm.BlockSize / 8, Integer))
        algorithm.Key = keyBuilder.GetBytes(CType(algorithm.KeySize / 8, Integer))
        algorithm.Padding = PaddingMode.PKCS7
        Return algorithm
    End Function
End Class

您应该将salt常量更改为其他内容。理想情况下,它甚至不是一个常数,因为为了使其尽可能安全,每次执行加密时都应该使用不同的盐,但这是另一个话题。

如果您希望将加密值返回为字符串而不是字节数组,您可以使用 Base-64 编码将字节数组转换为字符串和从字符串转换,如下所示:

Public Class Aes256Base64Encrypter
    Public Function Encrypt(ByVal plainText As String, ByVal secretKey As String) As String
        Dim encryptedPassword As String = Nothing
        Using outputStream As MemoryStream = New MemoryStream()
            Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
            Using cryptoStream As CryptoStream = New CryptoStream(outputStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write)
                Dim inputBuffer() As Byte = Encoding.Unicode.GetBytes(plainText)
                cryptoStream.Write(inputBuffer, 0, inputBuffer.Length)
                cryptoStream.FlushFinalBlock()
                encryptedPassword = Convert.ToBase64String(outputStream.ToArray())
            End Using
        End Using
        Return encryptedPassword
    End Function

    Public Function Decrypt(ByVal encryptedBytes As String, ByVal secretKey As String) As String
        Dim plainText As String = Nothing
        Using inputStream As MemoryStream = New MemoryStream(Convert.FromBase64String(encryptedBytes))
            Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
            Using cryptoStream As CryptoStream = New CryptoStream(inputStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read)
                Dim outputBuffer(0 To CType(inputStream.Length - 1, Integer)) As Byte
                Dim readBytes As Integer = cryptoStream.Read(outputBuffer, 0, CType(inputStream.Length, Integer))
                plainText = Encoding.Unicode.GetString(outputBuffer, 0, readBytes)
            End Using
        End Using
        Return plainText
    End Function

    Private Function getAlgorithm(ByVal secretKey As String) As RijndaelManaged
        Const salt As String = "put your salt here"
        Const keySize As Integer = 256

        Dim keyBuilder As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(secretKey, Encoding.Unicode.GetBytes(salt))
        Dim algorithm As RijndaelManaged = New RijndaelManaged()
        algorithm.KeySize = keySize
        algorithm.IV = keyBuilder.GetBytes(CType(algorithm.BlockSize / 8, Integer))
        algorithm.Key = keyBuilder.GetBytes(CType(algorithm.KeySize / 8, Integer))
        algorithm.Padding = PaddingMode.PKCS7
        Return algorithm
    End Function
End Class

如果您将加密值存储在文本文件、XML 文件甚至数据库中,则通常使用 Base-64 会更容易,就像这样。

于 2013-05-07T14:38:30.130 回答
2

存在处理加密的细微细节的高级加密库,因此您不会犯这些错误,KeyczarNaclGPGME

我将Keyczar 移植到 .net,它使用 AES 作为默认的对称加密。

您使用命令行程序使用随机 AES 密钥创建密钥集。

:> KeyczarTool.exe create --location=path_to_key_set --purpose=crypt
:> KeyczarTool.exe addkey --location=path_to_key_set --status=primary

在您要加密的项目中,

Using encrypter As New Encrypter("path_to_key_set")
     Return encrypter.Encrypt(plaintext)
End Using

然后解密

Using crypter As new Crypter("path_to_key_set")
     Return crypter.Decrypt(ciphertext)
End Using
于 2013-05-07T15:22:46.757 回答