Pertanyaan enkripsi sederhana / dekripsi di VB.Net


Saya mencoba mencari tahu bagaimana mengenkripsi / mendekripsi string di VB.Net.

Saya mengikuti contoh yang diberikan sini dan tulis kode berikut (di bawah). Ada kotak teks, tombol "mengenkripsi", dan tombol "dekripsi". Idenya adalah untuk mengetik sesuatu ke dalam kotak teks ("seperti 'hello world'"), klik "mengenkripsi", dan lihat versi terenkripsi muncul di kotak teks. Mengklik "dekripsi" kemudian akan membawa Anda kembali ke string asli.

Tetapi ketika saya mencoba untuk mengenkripsi saya mendapatkan kesalahan ketika saya mencoba "FlushFinalBlock". Kesalahannya adalah: "Panjang data untuk mengenkripsi tidak valid".

Bagian "dekripsi" adalah pengambilan total dalam gelap, karena contoh yang dikutip di atas hanya berkaitan dengan enkripsi, bukan dekripsi. Saya yakin itu salah, tetapi karena saya tidak bisa "mengenkripsi" untuk bekerja, saya belum mengujinya.

Adakah yang bisa memberitahu saya mengapa ini tidak berhasil?

Imports System.Data.SqlClient
Imports System.IO
Imports System.Security.Cryptography

Public Class Form1

  Private cryptObj As RijndaelManaged
  Private 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}
  Private IV_128 As Byte() = {234, 12, 52, 44, 214, 222, 200, 109, 2, 98, 45, 76, 88, 53, 23, 78}
  Private enc As System.Text.UTF8Encoding = New System.Text.UTF8Encoding()

  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 bPlainText As Byte() = Me.enc.GetBytes(Me.TextBox1.Text)
      Dim ms As MemoryStream = New MemoryStream()
      Dim cs As CryptoStream = New CryptoStream(ms, cryptObj.CreateEncryptor(), CryptoStreamMode.Write)
      cs.Write(bPlainText, 0, sPlainText.Length)
      cs.FlushFinalBlock()
      Me.TextBox1.Text = Me.enc.GetString(ms.ToArray())
    End If
  End Sub

  Private Sub btnDecrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDecrypt.Click
    Dim sCipherText = Me.TextBox1.Text
    Dim ms As MemoryStream = New MemoryStream()
    Dim cs As CryptoStream = New CryptoStream(ms, cryptObj.CreateDecryptor(), CryptoStreamMode.Read)
    cs.Read(Me.enc.GetBytes(sCipherText), 0, sCipherText.Length)
    Me.TextBox1.Text = Me.enc.GetString(ms.ToArray())
  End Sub

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Me.cryptObj = New RijndaelManaged()
    Me.cryptObj.BlockSize = 128
    Me.cryptObj.KeySize = 128
    Me.cryptObj.Mode = CipherMode.ECB
    Me.cryptObj.Padding = PaddingMode.None
    Me.cryptObj.Key = KEY_128
    Me.cryptObj.IV = IV_128
  End Sub

End Class

5
2017-11-02 15:28


asal


Jawaban:


Akhirnya saya menemukan jawabannya di sini:

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

Teladannya tampaknya sedikit rumit. Saya yakin itu mewakili kasus yang lebih umum dan fleksibel, tetapi saya dapat menghapus "saltPhrase", "initVector", dan penggunaan "PasswordDeriveBytes", yang tampaknya tidak digunakan lagi, tetapi saya juga menghindari diganti dengan nama buruk: Rfc2898DeriveBytes.

Berikut ini memungkinkan Anda memasukkan string berapa saja, mengenkripsi, dan mendekripsi ulang.

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

9
2017-11-04 18:13



Masalah yang saya lihat ada pada baris ini dalam kode enkripsi Anda:

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

Masalahnya adalah ini mengasumsikan array byte Anda sudah ada string UTF-8, hanya diukir sebagai array byte, padahal sebenarnya harus byte acak dan mungkin termasuk karakter yang tidak dapat ditulis. Ini bukan data utf-8 yang valid. Apa yang Anda ingin lakukan adalah base-64 encode yang menggunakan array byte Convert.ToBase64String () fungsi.

Kemudian, dekripsi Anda perlu benar mengkonversi basis 64 string kembali ke susunan byte, menggunakan Convert.FromBase64String () metode.


2
2017-11-02 17:15



Enkripsi Anda terlihat sebagian besar benar, tetapi saya tidak yakin apakah pengkodean UTF8 atau pengaturan lain pada objek enkripsi membuang Anda. Berikut adalah jantung dari metode enkripsi yang kami gunakan, sedikit disesuaikan dengan kode Anda:

' 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

Dan dekripsi adalah:

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

Satu perbedaan kecil adalah kami menerima kunci string dan intializaton dari pemanggil dan membersihkannya sebagai berikut.

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)

Pembersihan kunci enkripsi:

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)

Fungsi Akhir


1
2017-11-02 17:02



Berikut ini contoh kelas Enkripsi berdasarkan pada saya NextLevelEncryption Perpustakaan.

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

Untuk menggunakannya, yang harus Anda lakukan hanyalah memanggil fungsi Encrypt("Your text to encrypt here","Your password") dan Decrypt(""Your text to encrypt here","Your password").

Untuk informasi lebih lanjut, hubungi https://nextlevelencryption.codeplex.com/


1
2017-08-08 14:04