simple encrypting / decrypting in VB.Net

后端 未结 4 1126
执笔经年
执笔经年 2020-12-28 10:55

I\'m trying to figure out how to encrypt / decrypt a string in VB.Net.

I followed the example given here and wrote the following code (below). There\'s a text box,

相关标签:
4条回答
  • 2020-12-28 11:32

    The issue I spotted is on this line in your encryption code:

    Me.TextBox1.Text = Me.enc.GetString(ms.ToArray())

    The problem is that this assumes your byte array already is a UTF-8 string, just carved up as a byte array, when in fact it should be random bytes and likely includes unprintable characters. It's not valid utf-8 data. What you want to do instead is base-64 encode that byte array using the Convert.ToBase64String() function.

    Then, your decryption needs to correctly convert that base 64 string back to a byte array, using the Convert.FromBase64String() method.

    0 讨论(0)
  • 2020-12-28 11:36

    Your encryption looks mostly correct, but I am not sure if the UTF8 encoding or other settings on the encryption object is throwing you off. Here is the heart of the encryption method that we use, tailored slightly to your code:

    ' Return the encrypted bytes from the memory stream.
    Dim aoBytes As Byte() = Nothing
    
    ' Declare the RijndaelManaged object used to encrypt the data.
    Using oEncryptor As New RijndaelManaged
        Try
            ' Initialize the encryptor with the specified key and initialization vector
            oEncryptor.Key = KEY_128
            oEncryptor.IV = IV_128
    
            ' Declare the streams used to encrypt to an in memory array of bytes.
            Using msEncrypt As New MemoryStream
                ' Create the streams used for encryption.
                Using csEncrypt As New CryptoStream(msEncrypt, oEncryptor.CreateEncryptor(), CryptoStreamMode.Write)
                    Using swEncrypt As New StreamWriter(csEncrypt)
                        ' Write all data to the stream.
                        swEncrypt.Write(Me.TextBox1.Text)
                    End Using
    
                    ' Retrieve the bytes
                    aoBytes = msEncrypt.ToArray()
                End Using
    
            End Using
        Finally
            ' Clear the RijndaelManaged object.
            If oEncryptor IsNot Nothing Then
                oEncryptor.Clear()
            End If
        End Try
    End Using
    
    If aoBytes IsNot Nothing Then
        Me.TextBox1.Text = System.Convert.ToBase64String(aoBytes)
    Else
        Me.TextBox1.Text = String.Empty
    End If
    

    And the decryption is:

    Dim sDecryptedValue As String = ""
    
    ' Declare the RijndaelManaged object used to encrypt the data.
    Using oDecryptor As New RijndaelManaged
        Try
            ' Initialize the encryptor with the specified key and a default initialization vector
            oDecryptor.Key = KEY_128
            oDecryptor.IV = IV_128
    
            Using msDecrypt As New MemoryStream(System.Convert.FromBase64String(Me.TextBox1.Text))
                ' Create the streams used for encryption.
                Using csDecrypt As New CryptoStream(msDecrypt, oDecryptor.CreateDecryptor(), CryptoStreamMode.Read)
                    Using srDecrypt As New StreamReader(csDecrypt)
                        ' Write all data to the stream.
                        sDecryptedValue = srDecrypt.ReadToEnd()
                    End Using
                End Using
            End Using
        Finally
            ' Clear the RijndaelManaged object.
            If oDecryptor IsNot Nothing Then
                oDecryptor.Clear()
            End If
        End Try
    End Using
    
    Me.TextBox1.Text = sDecryptedValue
    

    One minor difference is that we accept a string key and intializaton vector from the caller and clean them up as follows.

    InitializationVector cleanup:

    If sInitializationVector.Length > 16 Then
        ' Trim the IV if it is too long
        sInitializationVector = sInitializationVector.Substring(0, 16)
    ElseIf sInitializationVector.Length < 16 Then
        ' Pad the IV if it is too short
        sInitializationVector = sInitializationVector.PadRight(16)
    End If
    
    oDecryptor.IV = System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(sInitializationVector)
    

    Encryption key cleanup:

    oDecryptor.Key = GetLegalEncryptionKey(sKey, oDecryptor)
    
    Public Function GetLegalEncryptionKey(ByVal sKey As String, ByVal oEncryptor As RijndaelManaged) As Byte()
    
    Dim sTemp As String
    
    If oEncryptor.LegalKeySizes.Length > 0 Then
        Dim wSize As Integer
        ' key sizes are in bits
    
        With oEncryptor.LegalKeySizes(0)
            wSize = .MinSize
            Do While sKey.Length * 8 > wSize AndAlso .SkipSize > 0 AndAlso wSize < .MaxSize
                wSize += oEncryptor.LegalKeySizes(0).SkipSize
            Loop
        End With
        Dim wTotalChars As Integer
    
        wTotalChars = CInt(wSize / 8)
        If sKey.Length > wTotalChars Then
            sTemp = sKey.Substring(0, wTotalChars)
        Else
            sTemp = sKey.PadRight(wTotalChars, " "c)
        End If
    Else
        sTemp = sKey
    End If
    
    ' convert the secret key to byte array
    Return System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(sTemp)
    

    End Function

    0 讨论(0)
  • 2020-12-28 11:44

    Ultimately I found the answer here:

    http://www.obviex.com/samples/Encryption.aspx

    His example seems a little over-complicated. I'm sure it represents a more general and flexible case, but I was able to do away with the "saltPhrase", the "initVector", and the use of "PasswordDeriveBytes", which apparently is deprecated anyway, but I also avoided its nastily named replacement: Rfc2898DeriveBytes.

    The following lets you enter a string of any length, encrypt it, and re-decrypt it.

    Imports System.Data.SqlClient
    Imports System.IO
    Imports System.Security.Cryptography
    
    Public Class Form1
    
      Private enc As System.Text.UTF8Encoding
      Private encryptor As ICryptoTransform
      Private decryptor As ICryptoTransform
    
      Private Sub btnEncrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEncrypt.Click
        Dim sPlainText As String = Me.TextBox1.Text
        If Not String.IsNullOrEmpty(sPlainText) Then
          Dim memoryStream As MemoryStream = New MemoryStream()
          Dim cryptoStream As CryptoStream = New CryptoStream(memoryStream, Me.encryptor, CryptoStreamMode.Write)
          cryptoStream.Write(Me.enc.GetBytes(sPlainText), 0, sPlainText.Length)
          cryptoStream.FlushFinalBlock()
          Me.TextBox1.Text = Convert.ToBase64String(memoryStream.ToArray())
          memoryStream.Close()
          cryptoStream.Close()
        End If
      End Sub
    
      Private Sub btnDecrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDecrypt.Click
        Dim cypherTextBytes As Byte() = Convert.FromBase64String(Me.TextBox1.Text)
        Dim memoryStream As MemoryStream = New MemoryStream(cypherTextBytes)
        Dim cryptoStream As CryptoStream = New CryptoStream(memoryStream, Me.decryptor, CryptoStreamMode.Read)
        Dim plainTextBytes(cypherTextBytes.Length) As Byte
        Dim decryptedByteCount As Integer = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length)
        memoryStream.Close()
        cryptoStream.Close()
        Me.TextBox1.Text = Me.enc.GetString(plainTextBytes, 0, decryptedByteCount)
      End Sub
    
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim KEY_128 As Byte() = {42, 1, 52, 67, 231, 13, 94, 101, 123, 6, 0, 12, 32, 91, 4, 111, 31, 70, 21, 141, 123, 142, 234, 82, 95, 129, 187, 162, 12, 55, 98, 23}
        Dim IV_128 As Byte() = {234, 12, 52, 44, 214, 222, 200, 109, 2, 98, 45, 76, 88, 53, 23, 78}
        Dim symmetricKey As RijndaelManaged = New RijndaelManaged()
        symmetricKey.Mode = CipherMode.CBC
    
        Me.enc = New System.Text.UTF8Encoding
        Me.encryptor = symmetricKey.CreateEncryptor(KEY_128, IV_128)
        Me.decryptor = symmetricKey.CreateDecryptor(KEY_128, IV_128)
      End Sub
    
    End Class
    
    0 讨论(0)
  • 2020-12-28 11:45

    Here is an example of an Encryption class based on my NextLevelEncryption library.

    Public Class Encryption
    ''' <summary>
    ''' Encrypt text using AES Algorithm
    ''' </summary>
    ''' <param name="text">Text to encrypt</param>
    ''' <param name="password">Password with which to encrypt</param>
    ''' <returns>Returns encrypted text</returns>
    ''' <remarks></remarks>
    Public Shared Function Encrypt(text As String, password 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 = ""
        Dim hash(31) As Byte
            Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(password))
            Array.Copy(temp, 0, hash, 0, 16)
            Array.Copy(temp, 0, hash, 15, 16)
            AES.Key = hash
            AES.Mode = Security.Cryptography.CipherMode.ECB
            Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
            Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(text)
            encrypted = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
            Return encrypted
    End Function
    
    ''' <summary>
    ''' Decrypt text using AES Algorithm
    ''' </summary>
    ''' <param name="text">Text to decrypt</param>
    ''' <param name="password">Password with which to decrypt</param>
    ''' <returns>Returns decrypted text</returns>
    ''' <remarks></remarks>
    Public Shared Function Decrypt(text As String, password 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 = ""
        Dim hash(31) As Byte
            Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(password))
            Array.Copy(temp, 0, hash, 0, 16)
            Array.Copy(temp, 0, hash, 15, 16)
            AES.Key = hash
            AES.Mode = Security.Cryptography.CipherMode.ECB
            Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateDecryptor
            Dim Buffer As Byte() = Convert.FromBase64String(text)
            decrypted = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
        Return decrypted
    End Function
    End Class
    

    To use it all you have to do is call the function Encrypt("Your text to encrypt here","Your password") and Decrypt(""Your text to encrypt here","Your password").

    For more information head over to https://nextlevelencryption.codeplex.com/

    0 讨论(0)
提交回复
热议问题