I'm having a great deal of difficulty finding a function or sub for vb (not C) that provides an easy way to convert a given string into a sha-1 (or sha512 ideally) hash.
If someone could provide a function in VB, it'd be extremely helpful.
Nearest attempt:
Function create_hash(ByVal password, ByVal salt)
Dim input As [Char]() = "string to hash".ToCharArray()
Dim secret As New SecureString()
For idx As Integer = 0 To input.Length - 1
secret.AppendChar(input(idx))
Next SecurePassword.MakeReadOnly()
Dim pBStr As IntPtr = Marshal.SecureStringToBSTR(secret)
Dim output As String = Marshal.PtrToStringBSTR(pBStr)
Marshal.FreeBSTR(pBStr)
Dim sha As SHA512 = New SHA512Managed()
Dim result As Byte() = sha.ComputeHash(Encoding.UTF8.GetBytes(output))
Return result
End Function
But this causes visual stuido to blue underline SecurePassword and Marshal at evey use. These are marked as undeclared variables, but declaring them causes other problems which I can't find a way to solve.
Take a look at the documentation for the System.Security.Cryptography.SHA512 class.
Dim data(DATA_SIZE) As Byte
Dim result() As Byte
Dim shaM As New SHA512Managed()
result = shaM.ComputeHash(data)
Like this (ignoring the salting you are doing at the top):
Function create_hash(ByVal password, ByVal salt) As Byte()
Dim sha As SHA512 = New SHA512Managed()
Dim result As Byte() = sha.ComputeHash(Encoding.UTF8.GetBytes(password & salt))
Return result
End Function
Related
I'm setting up a Login Form on Visual Basic .Net. I would like to have this database hosted over the internet, so people can connect wherever they are.
The trouble is, security. If I have a username and password in my code, I can easily be hacked, and my program will be cracked.
Is there any way to have a token that I can use instead of a password, that can only be accessed in through the program itself?
This is my code:
Dim connection As New MySqlConnection("datasource=localhost;port-3306;username;whatever;password=whatever;database=whatever")
And this is something like what I'm looking for:
Dim connection As New MySqlConnection("token=aFjiwqMF93JmHSazhH")
If so, how would I do this, and where would I get the database token and link from?
Anyone able to crack your program, will more likely have the knowledge to crack into MySQL too... I know, it's not an answer, I spent many weeks trying to secure my programs against similar, however, I then thought 'Why...?'
That being said, If you really need to keep your source code under wraps and passwords removed, how about loading the connection string from a text file somewhere?
Simple encryption see system.security.cryptography
I have just looked up my old code for encrypting strings simply, you can have a look at this
Imports System.Security.Cryptography
Imports System.Net
Public NotInheritable Class Encryptorr
Public TDS As New TripleDESCryptoServiceProvider
Private Function EncHash(ByVal key As String, ByVal length As Integer) As Byte()
Dim enc_Sha1 As New SHA1CryptoServiceProvider
Dim keyBytes() As Byte =
System.Text.Encoding.Unicode.GetBytes(key)
Dim hash() As Byte = enc_Sha1.ComputeHash(keyBytes)
ReDim Preserve hash(length - 1)
Return hash
End Function
Sub New(ByVal key As String)
TDS.Key = EncHash(key, TDS.KeySize \ 8)
TDS.IV = EncHash("", TDS.BlockSize \ 8)
End Sub
Public Function EncryptData(ByVal plaintext As String) As String
Dim Strbytes() As Byte = System.Text.Encoding.Unicode.GetBytes(plaintext)
Dim memStr As New System.IO.MemoryStream
Dim encStream As New CryptoStream(memStr, TDS.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write)
encStream.Write(Strbytes, 0, Strbytes.Length)
encStream.FlushFinalBlock()
Return Convert.ToBase64String(memStr.ToArray)
End Function
Public Function DecryptData(ByVal encryptedtext As String) As String
Try
Dim enc_Bytes() As Byte = Convert.FromBase64String(encryptedtext)
Dim mem_Str As New System.IO.MemoryStream
Dim decStream As New CryptoStream(mem_Str, TDS.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write)
decStream.Write(enc_Bytes, 0, enc_Bytes.Length)
decStream.FlushFinalBlock()
Return System.Text.Encoding.Unicode.GetString(mem_Str.ToArray)
Catch ex As Exception
Return "Decryption Failed"
End Try
End Function
End Class
Call with
Public Sub TestMe()
Dim encr As Encryptorr = New Encryptorr("AlovelyLong463728KeytoEncryptwith")
Dim encrytedstr As String = encr.EncryptData(textbox1.text)
Textbox2.text = encrytedstr
Dim decry As Encryptorr = New Encryptorr("AlovelyLong463728KeytoEncryptwith")
Dim decryptedtext As String = decry.DecryptData(Textbox2.text)
Textbox3.text = decryptedtext
End Sub
You can then encrypt and decrypt strings read from text files, although back to my original point. If someone can gain access to the program code, they can also work out the decryption too... :(
Still food for thought! Good luck
Update--
Just to add, you could always create the encrytped string, use that as a global variable and the decryt function to pass directly as your connection string. This means isnstead of saving the username and password in a text file, you just use Public Shared Constr as String = fhdasjifhn32437289cj (or whatever the encrypted string is) and the connection would be Dim Con as MySQLConnection = new MySQLConnection(DecryptMyStr(Constr)) with DecryptMyStr being the decrypt function
I have the following functions in a VB script:
Function DecryptSHA1(ByVal strOriginalString As String) As String
If strOriginalString = "" Then Return ""
Dim dEC_data() As Byte = Convert.FromBase64String(strOriginalString)
Dim dEC_Str As String = ASCIIEncoding.ASCII.GetString(dEC_data)
DecryptSHA1 = dEC_Str
End Function
Function EncryptSHA1(ByVal strOriginalString As String) As String
If strOriginalString = "" Then Return ""
Dim shaM As New SHA1Managed
Convert.ToBase64String(shaM.ComputeHash(Encoding.ASCII.GetBytes(strOriginalString)))
Dim eNC_data() As Byte = ASCIIEncoding.ASCII.GetBytes(strOriginalString)
Dim eNC_str As String = Convert.ToBase64String(eNC_data)
EncryptSHA1 = eNC_str
End Function
I don't code in VB but as much as I can see the functions have nothing to do with encrypting SHA1 but rater Base64 encoding and decoding. Am I wrong? The only thing that can make me think about hashing is the Dim shaM As New SHA1Managed line in the EncryptSHA1() function but the DecryptSHA1() function doesn't use it anymore. Are these simple Base64 encode/decode functions or more?
The only thing these functions do is converting to and from base64.
In the EncryptSHA1 function there is some SHA1 hashing code, but it is not actually used.
So there is no hashing nor encryption going on which makes the functions quite confusing.
I'm aware of the other thread on this issue (AES decryption error " The input data is not a complete block." Error vb.net), but I'm either not implementing the solutions offered there correctly, or something about my particular variant of this issue isn't covered by those solutions. In any event I'm getting the incomplete block error from the following code
Private GD As System.Security.Cryptography.Aes = System.Security.Cryptography.Aes.Create
Private PDB As New System.Security.Cryptography.Rfc2898DeriveBytes(EK, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D, &H65, &H64, &H76, &H65, &H64, &H65, &H76})
Public Function Decrypt(ByVal val As String) As String
Dim ret As String = Nothing
Dim TTB As New System.Text.UTF8Encoding
Try
Dim input() As Byte = TTB.GetBytes(val)
Using ms As New System.IO.MemoryStream(input)
Using cs As New System.Security.Cryptography.CryptoStream(ms, GD.CreateDecryptor(PDB.GetBytes(32), PDB.GetBytes(16)), Security.Cryptography.CryptoStreamMode.Read)
Using sr As New System.IO.StreamReader(cs)
ret = sr.ReadToEnd()
End Using
End Using
End Using
input = nothing
Catch ex As Exception
EL.AddErr("Encountered an error while decrypting the provided text for " & FName & ". Error Details: " & ex.Message, path)
End Try
Return ret
End Function
EK is my key, which I'll not be including. It's just a String though, nothing special.
I've tried several other methods to decrypt based on guidance on the MSDN site, DreamInCode, etc. None worked, but they all had different issues (typically returning a blank string). Seeing as this version of code closely mirrors my encryption code, I'd like to stick with it (or at least as close as I can while still having functional code).
Despite all comments, I still lack understanding of your intentions. Therefore, the sample code below may not provide what you exactly want, but at least should give an idea how to employ cryptographic functions. Particularly, the most notable difference from your approach is that the encryption key and initialization vector are computed once and for all messages, rather than reevaluated on each occasion, because the latter is prone to synchronization errors — such as when you reuse single crypto object to communicate with multiple parties, or when some messages get lost in transmission.
Public Shared Sub Test()
' Note: You should not actually hard-code any sensitive information in your source files, ever!
Dim sKeyPreimage As String = "MySuperPassword"
Dim oMyCrypto As New MyCrypto(sKeyPreimage)
Dim sPlaintext As String = "My super secret data"
Dim sEncrypted As String = oMyCrypto.EncryptText(sPlaintext)
Dim sDecrypted As String = oMyCrypto.DecryptText(sEncrypted)
Console.Out.WriteLine("Plaintext: {0}", sPlaintext) ' "My super secret data"
Console.Out.WriteLine("Encrypted: {0}", sEncrypted) ' "72062997872DC4B4D1BCBF48D5D30DF0D498B20630CAFA28D584CCC3030FC5F1"
Console.Out.WriteLine("Decrypted: {0}", sDecrypted) ' "My super secret data"
End Sub
Public Class MyCrypto
Private Shared TextEncoding As Text.Encoding = Text.Encoding.UTF8
Private CipherEngine As System.Security.Cryptography.SymmetricAlgorithm
' Note: Unlike in the question, same key and IV are reused for all messages.
Private CipherKey() As Byte
Private CipherIV() As Byte
Public Sub New(ByVal sKeyPreimage As String)
Dim abKeyPreimage() As Byte = TextEncoding.GetBytes(sKeyPreimage)
Dim abKeySalt() As Byte = TextEncoding.GetBytes("Ivan Medvedev")
Const KeyDerivationRounds As Integer = 1 << 12
Dim oKeyDerivationEngine As New System.Security.Cryptography.Rfc2898DeriveBytes(abKeyPreimage, abKeySalt, KeyDerivationRounds)
Me.CipherEngine = System.Security.Cryptography.Aes.Create()
Me.CipherEngine.Padding = Security.Cryptography.PaddingMode.PKCS7
Me.CipherKey = oKeyDerivationEngine.GetBytes(Me.CipherEngine.KeySize >> 3)
Me.CipherIV = oKeyDerivationEngine.GetBytes(Me.CipherEngine.BlockSize >> 3)
End Sub
Public Function Encrypt(ByVal abPlaintext() As Byte) As Byte()
Dim abCiphertext() As Byte
Using hStreamSource As New System.IO.MemoryStream(abPlaintext),
hStreamCipher As New System.Security.Cryptography.CryptoStream(
hStreamSource,
Me.CipherEngine.CreateEncryptor(Me.CipherKey, Me.CipherIV),
Security.Cryptography.CryptoStreamMode.Read),
hStreamTarget As New System.IO.MemoryStream
hStreamCipher.CopyTo(hStreamTarget)
abCiphertext = hStreamTarget.ToArray()
End Using
Return abCiphertext
End Function
Public Function Decrypt(ByVal abCiphertext() As Byte) As Byte()
Dim abPlaintext() As Byte
Using hStreamSource As New System.IO.MemoryStream(abCiphertext),
hStreamCipher As New System.Security.Cryptography.CryptoStream(
hStreamSource,
Me.CipherEngine.CreateDecryptor(Me.CipherKey, Me.CipherIV),
Security.Cryptography.CryptoStreamMode.Read),
hStreamTarget As New System.IO.MemoryStream
hStreamCipher.CopyTo(hStreamTarget)
abPlaintext = hStreamTarget.ToArray()
End Using
Return abPlaintext
End Function
Public Function EncryptText(ByVal sPlaintext As String) As String
Dim abPlaintext() As Byte = TextEncoding.GetBytes(sPlaintext)
Dim abCiphertext() As Byte = Me.Encrypt(abPlaintext)
Dim sCiphertext As String = Hex.Format(abCiphertext)
Return sCiphertext
End Function
Public Function DecryptText(ByVal sCiphertext As String) As String
Dim abCiphertext() As Byte = Hex.Parse(sCiphertext)
Dim abPlaintext() As Byte = Me.Decrypt(abCiphertext)
Dim sPlaintext As String = TextEncoding.GetChars(abPlaintext)
Return sPlaintext
End Function
End Class
Public Class Hex
Public Shared Function Format(ByVal abValue() As Byte) As String
Dim asChars(0 To abValue.Length * 2 - 1) As Char
Dim ndxChar As Integer = 0
For ndxByte As Integer = 0 To abValue.Length - 1
Dim bNibbleHi As Byte = abValue(ndxByte) >> 4, bNibbleLo As Byte = CByte(abValue(ndxByte) And &HFUS)
asChars(ndxChar) = Convert.ToChar(If(bNibbleHi <= 9, &H30US + bNibbleHi, &H37US + bNibbleHi)) : ndxChar += 1
asChars(ndxChar) = Convert.ToChar(If(bNibbleLo <= 9, &H30US + bNibbleLo, &H37US + bNibbleLo)) : ndxChar += 1
Next
Return New String(asChars)
End Function
Public Shared Function Parse(ByVal sValue As String) As Byte()
If String.IsNullOrEmpty(sValue) Then Return New Byte() {}
If (sValue.Length Mod 2) > 0 Then Return Nothing
Dim ndxText As Integer = 0
Dim ndxByteMax As Integer = (sValue.Length \ 2) - 1
Dim abValue(0 To ndxByteMax) As Byte
Try
For ndxByte As Integer = 0 To ndxByteMax
abValue(ndxByte) = Convert.ToByte(sValue.Substring(ndxText, 2), 16)
ndxText += 2
Next
Catch ex As Exception
Return Nothing
End Try
Return abValue
End Function
End Class
Again, please, note that this is just an example. I am not endorsing any kind of protection techniques shown here, especially because your task remains unknown. The code above simply illustrates the syntax and semantics — not how to do it right.
I have this method
Public Shared Function HashPassword(ByVal password As String) As String
Dim algorithm As HashAlgorithm
algorithm = SHA1.Create
Dim data As Byte() = algorithm.ComputeHash(Encoding.UTF8.GetBytes(password))
Dim HashedPassword As String = ""
Dim i As Integer = 0
Do While i < data.Length
HashedPassword &= data(i).ToString("x2").ToLowerInvariant()
i += 1
Loop
Return HashedPassword
End Function
How can I decode a string which has been encoded by this function?
A hash is a one way so you dont decrypt them. Instead, compare the new input value to the stored hash to verify. If you want to encrypt/decrypt data (not the best way to protect passwords), then you need to encrypt, not hash.
But there may be a problem with your method: the result is usually converted to base64 for storing/saving. A hex string might work (never tried) but there is a built in way for this:
Public Shared Function HashPassword(password As String) As String
Dim algorithm As HashAlgorithm
algorithm = SHA1.Create
Dim data As Byte() = algorithm.ComputeHash(Encoding.UTF8.GetBytes(password))
Return Convert.ToBase64String(data)
End Function
So, new user registration would be something like:
hashedPW = HashPassword(thePWText)
To check it later:
thisPW = HashPassword(PWInput)
If thisPW = hashedPW Then
' user knows the PW
Else
' wrong password
End If
I'm having hard time with this one. Can someone either point me in the right direction for checking/building hash codes for an uploaded file or else tell me what I'm doing wrong with the code below?
getFileSHA256(softwareUpload.PostedFile) 'Line that calls the function includes a reference to an uploaded file
Private Function getFileSHA256(ByVal theFile As Web.HttpPostedFile) As String
Dim SHA256CSP As New SHA256Managed()
Dim byteHash() As Byte = SHA256CSP.ComputeHash(theFile.InputStream)
Return ByteArrayToString(byteHash)
End Function
Private Function ByteArrayToString(ByVal arrInput() As Byte) As String
Dim sb As New System.Text.StringBuilder(arrInput.Length * 2)
For i As Integer = 0 To arrInput.Length - 1
sb.Append(arrInput(i).ToString("X2"))
Next
Return sb.ToString().ToLower
End Function
I should add that the function works, but the return does not match other programs' sha256 values.
EDIT ------
There are two other functions that I'm using in my code. SHA1 gets the same kind of results as the SHA256; the results do not match trusted sources.
However, the MD5 works as expected.
Private Function getFileSHA1(ByVal theFile As Web.HttpPostedFile) As String
Dim SHA1CSP As New SHA1CryptoServiceProvider()
Dim byteHash() As Byte = SHA1CSP.ComputeHash(theFile.InputStream)
Return ByteArrayToString(byteHash)
End Function
Private Function getFileMd5(ByVal theFile As Web.HttpPostedFile) As String
Dim Md5CSP As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim byteHash() As Byte = Md5CSP.ComputeHash(theFile.InputStream)
Return ByteArrayToString(byteHash)
End Function
I plan to consolidate these functions once I know they are working as expected.
The only difference between these is that MD5 is using "MD5CryptoServiceProvider" and it works as expected. SHA1 is also using "SHA1CryptoServiceProvider" but it does not match trusted sources.
I did some testing here, it appears that for text files SHA256Managed works perfectly.
My code is below, I used your implementation of ByteArrayToString:
Sub Main()
Dim s As New SHA256Managed
Dim fileBytes() As Byte = IO.File.ReadAllBytes("s:\sha256.txt")
Dim hash() As Byte = s.ComputeHash(fileBytes)
Dim referenceHash As String = "18ffd9682c5535a2b2798ca51b13e9490df326f185a83fe6e059f8ff47d92105"
Dim calculatedHash As String = ByteArrayToString(hash)
MsgBox(calculatedHash = referenceHash) 'outputs True
End Sub
Private Function ByteArrayToString(ByVal arrInput() As Byte) As String
Dim sb As New System.Text.StringBuilder(arrInput.Length * 2)
For i As Integer = 0 To arrInput.Length - 1
sb.Append(arrInput(i).ToString("X2"))
Next
Return sb.ToString().ToLower
End Function
For testing purposes, I created a file called sha256.txt under S: with the following contents:
my test file
(no trailing spaces or newline)
I got the reference hash value from here, by feeding same data.
Also check this and this - the fact you get non-match could be related to platform and/or implementation of your trusted source, or needing an extra conversion step.