AES Encrypt String in VB.NET
I have a program based in Visual Basic 2010.
I want to use a custom keyword and AES encryption to generate registration keys on our company website, that will unlock the software regardless of whether or not the software is connected to the internet.
To do this, I want to encrypt certain user information (and a validation code) into an AES encrypted string using a utility I'll build on my website. Then, I want my program to decrypt the string into the user information and validation code, then use that information to validate the registration key.
Which brings me to the question - how do I encrypt and decrypt a string in AES programatically? Is there a code template I can use somewhere, or a built in method?
A quick Google Search brings up the following functions: I've not tested whether the output they produce is correct, however they do appear to compile correctly.
Public Function AES_Encrypt(ByVal input As String, ByVal pass 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 = Security.Cryptography.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
End Try
End Function
Public Function AES_Decrypt(ByVal input As String, ByVal pass 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 = Security.Cryptography.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
End Try
End Function
Sourced from: http://www.l33thackers.com/Thread-VB-NET-AES-Encryption
Edit: Thanks to Artjom B. for notifying me for a mistake in decryption of AES-CBC that occured due to my false assumption that the IV strings always end with == (in Base64) which is wrong. Thanks to Kanky for bringing this topic up and thanks to Misery for offering a solution to it in this link. Note that I didn't check his/her fix myself, but hopefully it is correct.
Below are two solutions for encrypting strings with AES. First one uses CBC mode with an auto-generated IV and is more secure. The use of IV with CBC mode ensures that even the same plaintext-key pairs result in distinct ciphertexts and thus makes it more secure. Second one uses ECB more and shouldn't be used for repetitive plaintext encryption. AES.Key is generated by hashing the input key string with SHA256; so you don't have to worry about pseudorandomness of your key.
This one is AES-CBC. IV is auto-generated by the built-in function and concatenated with the ciphertext and returned as the output of the encryption algorithm. Decryption algorithm splits this concatenated text to recover the IV and the actual ciphertext.
Private Function AESE(ByVal plaintext As String, ByVal key As String) As String
Dim AES As New System.Security.Cryptography.RijndaelManaged
Dim SHA256 As New System.Security.Cryptography.SHA256Cng
Dim ciphertext As String = ""
Try
AES.GenerateIV()
AES.Key = SHA256.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(key))
AES.Mode = Security.Cryptography.CipherMode.CBC
Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(plaintext)
ciphertext = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Return Convert.ToBase64String(AES.IV) & Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Catch ex As Exception
Return ex.Message
End Try
End Function
Private Function AESD(ByVal ciphertext As String, ByVal key As String) As String
Dim AES As New System.Security.Cryptography.RijndaelManaged
Dim SHA256 As New System.Security.Cryptography.SHA256Cng
Dim plaintext As String = ""
Dim iv As String = ""
Try
Dim ivct = ciphertext.Split({"=="}, StringSplitOptions.None)
iv = ivct(0) & "=="
ciphertext = If(ivct.Length = 3, ivct(1) & "==", ivct(1))
AES.Key = SHA256.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(key))
AES.IV = Convert.FromBase64String(iv)
AES.Mode = Security.Cryptography.CipherMode.CBC
Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateDecryptor
Dim Buffer As Byte() = Convert.FromBase64String(ciphertext)
plaintext = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Return plaintext
Catch ex As Exception
Return ex.Message
End Try
End Function
This one below is AES-ECB mode. It doesn't use an IV. The same plaintexts always result in the same ciphertexts (under the same key of course) and vice versa.
Private Function AESE(ByVal input As Byte(), ByVal key As String) As Byte()
Dim AES As New System.Security.Cryptography.RijndaelManaged
Dim SHA256 As New System.Security.Cryptography.SHA256Cng
Dim ciphertext As String = ""
Try
AES.Key = SHA256.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(key))
AES.Mode = Security.Cryptography.CipherMode.ECB
Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
Dim Buffer As Byte() = input
Return DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)
Catch ex As Exception
End Try
End Function
Private Function AESD(ByVal input As Byte(), ByVal key As String) As Byte()
Dim AES As New System.Security.Cryptography.RijndaelManaged
Dim SHA256 As New System.Security.Cryptography.SHA256Cng
Try
AES.Key = SHA256.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(key))
AES.Mode = Security.Cryptography.CipherMode.ECB
Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateDecryptor
Dim Buffer As Byte() = input
Return DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)
Catch ex As Exception
End Try
End Function
Below are two examples for AES and 3DES encryption. These use byte arrays as the input and output but you can easily modify to handle strings. As a good practice you should always generate the initialization vector (IV) and prepend it to the output file for decrypting. This helps protect your KEY from brute force attacks. It's also better to use CBC rather than EBC for the cipher mode.
Imports System.Security.Cryptography
Imports System.Text
Public Class CAes
'************************************************************************************************
'Functions for AES Encryption
'************************************************************************************************
Public Function AES_Encrypt(ByVal value As Byte(), ByVal key As String) As Byte()
Dim AES As New RijndaelManaged
Dim SHA256 As New SHA256Cng
Dim output() As Byte
AES.GenerateIV()
Dim iv() As Byte = AES.IV
AES.Key = SHA256.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key))
AES.Mode = CipherMode.CBC
Dim AESEncrypter As ICryptoTransform = AES.CreateEncryptor
Dim Buffer As Byte() = value
output = AESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)
'Copy the IV as the first 16 bytes of the output then copy encrypted bytes
Dim ivAndOutput(output.Length - 1 + 16) As Byte
Array.Copy(iv, ivAndOutput, 16)
Array.Copy(output, 0, ivAndOutput, 16, output.Length)
Return ivAndOutput
End Function
Public Function AES_Decrypt(ByVal value As Byte(), ByVal key As String) As Byte()
Dim AES As New RijndaelManaged
Dim SHA256 As New SHA256Cng
Dim output() As Byte
Dim iv(15) As Byte
Dim Buffer(value.Length - 1 - 16) As Byte
'Extract first 16 bytes of input stream as IV. Copy remaining bytes into encrypted buffer
Array.Copy(value, iv, 16)
Array.Copy(value, 16, Buffer, 0, value.Length - 16)
AES.Key = SHA256.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key))
AES.IV = iv
AES.Mode = CipherMode.CBC
Dim AESDecrypter As ICryptoTransform = AES.CreateDecryptor
output = AESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)
Return output
End Function
End Class
Public Class C3Des
'************************************************************************************************
'Functions for 3DES Encryption
'************************************************************************************************
Public Function DES_Encrypt(ByVal value As Byte(), ByVal key As String) As Byte()
Dim m As MD5 = New MD5CryptoServiceProvider
Dim d As TripleDES = New TripleDESCryptoServiceProvider
Dim encryptBytes() As Byte
d.Key = m.ComputeHash(Encoding.Unicode.GetBytes(key))
d.GenerateIV()
Dim c As ICryptoTransform = d.CreateEncryptor
Dim input() As Byte = value
encryptBytes = c.TransformFinalBlock(input, 0, input.Length)
Dim outBytes(encryptBytes.Length + d.IV.Length - 1) As Byte
Array.Copy(d.IV, outBytes, d.IV.Length)
Array.Copy(encryptBytes, 0, outBytes, 8, encryptBytes.Length)
Return outBytes
End Function
Public Function DES_Decrypt(ByVal value As Byte(), ByVal key As String) As Byte()
Dim m As MD5 = New MD5CryptoServiceProvider
Dim d As TripleDES = New TripleDESCryptoServiceProvider
Dim encryptBytes(value.Length - 9), iv(7) As Byte
Array.Copy(value, 0, iv, 0, 8)
Array.Copy(value, 8, encryptBytes, 0, value.Length - 8)
d.Key = m.ComputeHash(Encoding.Unicode.GetBytes(key))
d.IV = iv
Dim b As Byte() = encryptBytes
Dim c As ICryptoTransform = d.CreateDecryptor
Dim output() As Byte = c.TransformFinalBlock(b, 0, b.Length)
Return output
End Function
End Class