I have an login system in VB and it encodes the password:
'Hash password
'Create salt (randomness)
Dim salt(16) As Byte
Dim rng = New RNGCryptoServiceProvider()
rng.GetBytes(salt)
For Each t In salt
Debug.WriteLine(t.ToString())
Next
'Hash
Dim pbkdf2 = New Rfc2898DeriveBytes(TxtPassword.Text, salt, 10000)
Dim hash As Byte() = pbkdf2.GetBytes(20)
'Combine salt and password
Dim hashBytes(36) As Byte
Array.Copy(salt, 0, hashBytes, 0, 16)
Array.Copy(hash, 0, hashBytes, 16, 20)
'Convert to string
Dim savedPasswordHash As String = Convert.ToBase64String(hashBytes)
After that it saves it in my mysql database.
Then someone wants to login:
'Fetch the stored value
Dim savedPasswordHash As String = usersRows.GetString("password")
'Extract the bytes
Dim hashBytes() = Convert.FromBase64String(savedPasswordHash)
'Get the salt
Dim salt(16) As Byte
Array.Copy(hashBytes, 0, salt, 0, 16)
For Each t In salt
Debug.WriteLine(t.ToString())
Next
For Each t In hashBytes
Debug.WriteLine(t.ToString())
Next
Debug.WriteLine(savedPasswordHash)
'Compute the hash on the password the user entered
Dim pbkdf2 = New Rfc2898DeriveBytes(TxtPassword.Text, salt, 10000)
Dim hash As Byte() = pbkdf2.GetBytes(20)
'Correct password variable
Dim passwordCorrect As Boolean = True
'Compare the results
Dim hashed(20) As Byte
Array.Copy(hashBytes, 16, hashed, 0, 20)
If Not hashed.Equals(hash) Then
passwordCorrect = False
End If
Debug.WriteLine(passwordCorrect)
Every thing works fine, but the Convert.FromBase64String(savedPasswordHash) is not the same byte array as I originally put in but the savedPasswordHash is the same as my original string Convert.ToBase64String(hashBytes).
Related
Can't reproduce an AES online encoder example using VB.Net
Trying in https://www.devglan.com/online-tools/aes-encryption-decryption with following parameters:
Text to be Encrypted: test
Cipher Mode: ECB
Key Size: 128
Secret Key: 1234567890123456
I get this output: 3fvaLg5IDlveswuXzhVQcw==
If I try in VB.Net using this function (found in https://gist.github.com/ShaneGowland/5973974):
Public Shared 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 = 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
Return ex.ToString
End Try
End Function
I get this output: 6mhZOr1dQ7PWqbRGzmMgjg== which is not matching with got at devglan.com
I tried with different paddings with no luck. What am I doing wrong?
PS: I am aware that the ECB method should not be used
Working with this function:
Public Shared 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
AES.Mode = CipherMode.ECB
AES.Key = Encoding.UTF8.GetBytes(pass)
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
Return ex.ToString
End Try
End Function
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.
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.
I have an issue when trying to switch between 256 and 128 bit encryption with my code. If I keep it at 256bit, it works fine, but when I try it again using a 128 bit key, I get an error of "Padding is invalid and cannot be removed." Any help is much appreciated. I am no pro at encryption. The error is thrown when the "DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)" part of the AES_Decrypt function is called.
Public Shared Function GenerateEncryptionKey(Optional ByVal keySizeIndex As Integer = 1) As Byte()
'Generate a Key.
Dim rm As RijndaelManaged = New RijndaelManaged()
Select Case keySizeIndex
Case 0
rm.KeySize = 128
Case 1
rm.KeySize = 256
Case Else
rm.KeySize = 256
End Select
rm.GenerateKey()
Return rm.Key
End Function
Public Shared Function AES_Encrypt(ByVal input As String, ByVal pass As Byte()) As String
Dim AES As New RijndaelManaged
Dim encrypted As String = ""
Dim hash As Byte()
Dim byteLength As Integer
Try
byteLength = pass.Length
ReDim hash(byteLength - 1)
Array.Copy(pass, 0, hash, 0, 16)
If (byteLength > 16) Then
Array.Copy(pass, 0, hash, 15, 16)
End If
AES.Key = hash
AES.Mode = Security.Cryptography.CipherMode.ECB
Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
Dim Buffer As Byte() = System.Text.Encoding.Unicode.GetBytes(input)
'Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(input)
Dim testBuffer As Byte() = DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)
encrypted = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Catch ex As Exception
encrypted = ""
End Try
Return encrypted
End Function
Public Shared Function AES_Decrypt(ByVal input As String, ByVal pass As Byte()) As String
Dim AES As New RijndaelManaged
Dim decrypted As String = ""
Dim hash As Byte()
Dim byteLength As Integer
Try
byteLength = pass.Length
ReDim hash(byteLength - 1)
Array.Copy(pass, 0, hash, 0, 16)
If (byteLength > 16) Then
Array.Copy(pass, 0, hash, 15, 16)
End If
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)
Dim testBuffer As Byte() = DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)
decrypted = System.Text.Encoding.Unicode.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
'decrypted = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
Catch ex As Exception
decrypted = ""
End Try
Return decrypted
End Function
I have used the following function to encrypt my password:
HashPasswordForStoringInConfigFile(Password, "MD5")
Now I want to decrypt the password again.
Note I'm showing the encrypted password in a grid-view and I want to decrypt it when the particular row goes in edit mode.
The simple answer is "you can't"
The idea of hashing is to generate a "safe" code from the real password, where that code can be stored in clear text; in a database (or text file) somewhere where other users might be seeing it somehow.
When someone tries to login, your system would compute another hash from the new login and then compare with the existing hash from your existing database, if the hash matches, then you know it's the correct password and then you can allow them to login, otherwise, it's not the same password / login-failed.
The reason why you cannot reverse the hash is because a hash is computed by doing the following steps:
1) Taking the password into some algorithm to:
2) Generate a very large string, then:
3) Chop that string and:
4) Take a part of it as your "hash"
So you see, even if you are superman in decoding and can figure the algorithm out, and know the hash code, and managed to reverse it back into the original form, then you would still have parts of the password missing, hence unsuccessful.
This is why Hashes are secure.
I hope this explains it.
you can make encrypt and decrypt function like this to encrypt and decrypt your text , and further u can use as per your need to display the decrypt text
here is the function
Public Function Encrypt(ByVal plainText As String) As String
Dim passPhrase As String = "yourPassPhrase"
Dim saltValue As String = "mySaltValue"
Dim hashAlgorithm As String = "MD5"
Dim passwordIterations As Integer = 2
Dim initVector As String = "#1B2c3D4e5F6g7H8"
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(plainText)
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 = Convert.ToBase64String(cipherTextBytes)
Return cipherText
End Function
and for decrypt use this
Public Function Decrypt(ByVal cipherText As String) As String
Dim passPhrase As String = "yourPassPhrase"
Dim saltValue As String = "mySaltValue"
Dim hashAlgorithm As String = "MD5"
Dim passwordIterations As Integer = 2
Dim initVector As String = "#1B2c3D4e5F6g7H8"
Dim keySize As Integer = 256
' Convert strings defining encryption key characteristics into byte
' arrays. Let us assume that strings only contain ASCII codes.
' If strings include Unicode characters, use Unicode, UTF7, or UTF8
' encoding.
Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(initVector)
Dim saltValueBytes As Byte() = Encoding.ASCII.GetBytes(saltValue)
' Convert our ciphertext into a byte array.
Dim cipherTextBytes As Byte() = Convert.FromBase64String(cipherText)
' First, we must create a password, from which the key will be
' derived. This password will be generated from the specified
' passphrase and salt value. The password will be created using
' the specified hash algorithm. Password creation can be done in
' several iterations.
Dim password As New PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations)
' Use the password to generate pseudo-random bytes for the encryption
' key. Specify the size of the key in bytes (instead of bits).
Dim keyBytes As Byte() = password.GetBytes(keySize \ 8)
' Create uninitialized Rijndael encryption object.
Dim symmetricKey As New RijndaelManaged()
' It is reasonable to set encryption mode to Cipher Block Chaining
' (CBC). Use default options for other symmetric key parameters.
symmetricKey.Mode = CipherMode.CBC
' Generate decryptor from the existing key bytes and initialization
' vector. Key size will be defined based on the number of the key
' bytes.
Dim decryptor As ICryptoTransform = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)
' Define memory stream which will be used to hold encrypted data.
Dim memoryStream As New MemoryStream(cipherTextBytes)
' Define cryptographic stream (always use Read mode for encryption).
Dim cryptoStream As New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
' Since at this point we don't know what the size of decrypted data
' will be, allocate the buffer long enough to hold ciphertext;
' plaintext is never longer than ciphertext.
Dim plainTextBytes As Byte() = New Byte(cipherTextBytes.Length - 1) {}
' Start decrypting.
Dim decryptedByteCount As Integer = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length)
' Close both streams.
memoryStream.Close()
cryptoStream.Close()
' Convert decrypted data into a string.
' Let us assume that the original plaintext string was UTF8-encoded.
Dim plainText As String = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount)
' Return decrypted string.
Return plainText
End Function
and call the function you will get the result.
I figured this would be pretty straight forward but I have an issue with getting my AES Encryption function to return a Hex String. I can get it to work when I convert it to Base64 but I cannot get the String with Hex values. Here is my code. Any help would be appreciated.
Dim AES_ENCRYPTION As New System.Security.Cryptography.RijndaelManaged
Dim CODE_AES As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim encrypted As String = ""
Try
Dim hash(31) As Byte
Dim temp As Byte() = CODE_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
Array.Copy(temp, 0, hash, 0, 16)
Array.Copy(temp, 0, hash, 15, 16)
AES_ENCRYPTION.Key = hash
AES_ENCRYPTION.Mode = CipherMode.ECB
Dim AES_ENCRYPTOR As System.Security.Cryptography.ICryptoTransform = AES_ENCRYPTION.CreateEncryptor
Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(input)
encrypted = (Conversion.Hex(AES_ENCRYPTOR.TransformFinalBlock(Buffer, 0, Buffer.Length)))
Catch ex As Exception
End Try
Return encrypted
I've tried your example, and I've got nothing either.
So what I tried instead of having encrypted = (Conversion.Hex(AES_ENCRYPTOR.TransformFinalBlock(Buffer, 0, Buffer.Length))), I have used a loop to convert each byte to its hex equivalent, and concatenate it to encrypted.
Dim encrypted_byte() As Byte = AES_ENCRYPTOR.TransformFinalBlock(Buffer, 0, Buffer.Length)
For i As Integer = 0 To encrypted_byte.Length - 1
encrypted = encrypted & Hex(encrypted_byte(i)).ToUpper
Next
I'm not sure how you formatted your hex string in Java, but this should be at least a start.