Jason Edel-Brock Jason Edel-Brock - 4 months ago 18
Vb.net Question

VB.Net Encryption Function Not Decrypting Without Using Base64Encode

I am having a issue with decrypting, my goal is to be able to encrypt/decrypt with/without base64 encoding on the encrypted string. As of now I can encrypt/decrypt with base64 and encrypt without it but not decrypt without it. I get errors regarding the padding being incorrect.

Thanks in advance!

Here is my encryption/decryption function:

Public Function DoCryptWork(Type As String, Data As String) As String

Dim Pass As String = Hasher.TextBoxPassword.Text
Dim Salt As String = Hasher.TextBoxSalt.Text
Dim Vect As String = Hasher.TextBoxIntVector.Text

Select Case Type

Case "e"

Try

Dim PassPhrase As String = Pass
Dim SaltValue As String = Salt
Dim HashAlgorithm As String = My.Settings.HashAlgorithm
Dim PasswordIterations As Integer = 2
Dim InitVector As String = Vect
Dim KeySize As Integer = 256
Dim InitVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitVector)
Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(SaltValue)
Dim PlainTextBytes As Byte() = Encoding.UTF8.GetBytes(Data)
Dim Password As New PasswordDeriveBytes(PassPhrase, SaltValueBytes, HashAlgorithm, PasswordIterations)
Dim KeyBytes As Byte() = Password.GetBytes(KeySize \ 8)
Dim SymmetricKey As New RijndaelManaged()

SymmetricKey.Mode = CipherMode.CBC

Dim Encryptor As ICryptoTransform = SymmetricKey.CreateEncryptor(KeyBytes, InitVectorBytes)
Dim MemoryStream As New MemoryStream()
Dim CryptoStream As New CryptoStream(MemoryStream, Encryptor, CryptoStreamMode.Write)

CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length)
CryptoStream.FlushFinalBlock()

Dim CipherTextBytes As Byte() = MemoryStream.ToArray()

MemoryStream.Close()
CryptoStream.Close()

Dim CipherText As String = Nothing

If My.Settings.Base64EncodeMD5Hash = True Then

CipherText = Convert.ToBase64String(CipherTextBytes)

Return CipherText

Else

Dim TextCipher As New StringBuilder()

For n As Integer = 0 To CipherTextBytes.Length - 1

TextCipher.Append(CipherTextBytes(n).ToString("X2"))

Next n

CipherText = TextCipher.ToString()

Return CipherText

End If

Catch ex As Exception

MsgBox("Encryption was unsuccessfull!", MsgBoxStyle.Critical, "Error")

Return "Encryption was unsuccessfull!"

End Try

Case "d"

Try

Dim PassPhrase As String = Pass
Dim SaltValue As String = Salt
Dim HashAlgorithm As String = My.Settings.HashAlgorithm
Dim PasswordIterations As Integer = 2
Dim InitVector As String = Vect
Dim KeySize As Integer = 256
Dim InitVectorBytes As Byte() = Encoding.ASCII.GetBytes(InitVector)
Dim SaltValueBytes As Byte() = Encoding.ASCII.GetBytes(SaltValue)
Dim CipherTextBytes As Byte() = Nothing

If My.Settings.Base64EncodeMD5Hash = True Then

CipherTextBytes = Convert.FromBase64String(Data)

Else

Dim bytedata As Byte() = Encoding.UTF8.GetBytes(Data)

CipherTextBytes = bytedata

End If

Dim Password As New PasswordDeriveBytes(PassPhrase, SaltValueBytes, HashAlgorithm, PasswordIterations)
Dim KeyBytes As Byte() = Password.GetBytes(KeySize \ 8)
Dim SymmetricKey As New RijndaelManaged()

SymmetricKey.Mode = CipherMode.CBC

Dim Decryptor As ICryptoTransform = SymmetricKey.CreateDecryptor(KeyBytes, InitVectorBytes)
Dim MemoryStream As New MemoryStream(CipherTextBytes)
Dim CryptoStream As New CryptoStream(MemoryStream, Decryptor, CryptoStreamMode.Read)
Dim PlainTextBytes As Byte() = New Byte(CipherTextBytes.Length - 1) {}
Dim DecryptedByteCount As Integer = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length)

MemoryStream.Close()
CryptoStream.Close()

Dim PlainText As String = Encoding.UTF8.GetString(PlainTextBytes, 0, DecryptedByteCount)

Return PlainText

Catch Ex As Exception

MsgBox("Decryption was unsuccessfull!" & vbNewLine & vbNewLine & Ex.ToString(), MsgBoxStyle.Critical, "Error")

Return "Decryption was unsuccessfull!"

End Try

Case Else

Return "Error! Invalid Case Selected We should never see this but just to be safe we'll show this message if the wrong case is selected!"

End Select

Return True

End Function


I call the function as so:

TextBoxOutput.Text = Encryption.DoCryptWork("e", TextBoxInput.Text) ' encrypt data.
TextBoxOutput.Text = Encryption.DoCryptWork("d", TextBoxInput.Text) ' decrypt data.

Answer

When you convert the bytes to hex, you output two hex digits per byte. When you convert that hex back to bytes, you're converting every hex digit to a byte instead of every pair of hex digits.

Actually, I just took another look and noticed that you're not even keeping the earlier bytes. This loop:

For n As Integer = 0 To Data.Length - 1
    CipherTextBytes = Convert.ToByte(Data(n))
Next n

sets CipherTextBytes on each iteration so you're going to replace the previous byte each time, so you only end up keeping the byte from the last digit.

Comments