I am trying to build an application where security and encryption are a high concern.
I am using Visual Studio 2022 and VB.NET 6.0 (I searched for 3 days now and couldn't find a suitable solution, all that I found is related to a different version of .NET and NOT Visual Studio 2022)
UPDATE: 16/5/2022
I updated my question to be more related to what I really need; which is hashing the password.
Thank you
This solution worked for me like charm:
Imports System.Security.Cryptography
Imports System.Text
Public Module hashing
Public Function PWDhash(ByVal password As String)
Using sha512Hash As SHA512 = SHA512.Create()
Return GetHash(sha512Hash, password)
End Using
End Function
Private Function GetHash(ByVal hashAlgorithm As HashAlgorithm, ByVal input As String) As String
' Convert the input string to a byte array and compute the hash.
Dim data As Byte() = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(input))
' Create a new Stringbuilder to collect the bytes
' and create a string.
Dim sBuilder As New StringBuilder()
' Loop through each byte of the hashed data
' and format each one as a hexadecimal string.
For i As Integer = 0 To data.Length - 1
sBuilder.Append(data(i).ToString("x2"))
Next
' Return the hexadecimal string.
Return sBuilder.ToString()
End Function
' Verify a hash against a string.
Public Function VerifyHash(hashAlgorithm As HashAlgorithm, input As String, hash As String) As Boolean
' Hash the input.
Dim hashOfInput As String = GetHash(hashAlgorithm, input)
' Create a StringComparer an compare the hashes.
Dim comparer As StringComparer = StringComparer.OrdinalIgnoreCase
Return comparer.Compare(hashOfInput, hash) = 0
End Function
End Module
This is how to hash:
Dim HashedPWD As String = PWDhash("password here")
This is how to verify:
Dim IsPWDCorrect As Boolean = VerifyHash(sha512Hash, "password here", "password hash from DB")
I also created a function to force user to choose a complex password.
It works on VB.Net Core 6.0
The length of the hash is 128 Byte.
This is an example output:
708ed38ae70f96bc7dcb58515ab328614eaf3b41402de0c50e60ba0f56be5efc6f6daf0b226ec238c3dcaff182e466a1e12df1cadd4e62e6a8c197355b1edc4e
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.
So, I got a bit of a problem here, I got a database, a login and a registration, all in different classes, now I need to hash the password in the database and read it out again when logging in, but I don't know how to handle this, I already searched a lot but couldn't find anything useful.
Here is my login class
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlServerCe
Public Class Login
Inherits System.Web.UI.Page
Private Sub LSend_Click(sender As Object, e As System.EventArgs) Handles LSend.Click
If Bibliothek.EntryExists(LNAME.Text, "Username") = False Then
LNAMELBL.Text = "Name oder Passwort Falsch."
Exit Sub
End If
If Bibliothek.EntryExists(LPW.Text, "Passwort") = False Then
LNAMELBL.Text = "Name oder Passwort Falsch."
Exit Sub
End If
Dim UserN As String = LNAME.Text
Session("Admin") = Bibliothek.GetValueBool(UserN, "IsAdmin")
Session("USERNA") = Bibliothek.GetValueBool(UserN, "Username")
Response.Redirect("/TSL/Home.aspx")
End Sub
Private Sub REG_Click(sender As Object, e As System.EventArgs) Handles REG.Click
Response.Redirect("/TSL/Registrierung.aspx")
End Sub
End Class
It is important to note that MD5 is no longer considered a good way to hash data you wish to protect. See wikipedia for a discussion of the vulnerabilities.
See this answer for hashing using SHA.
For passwords, you'd save the hash of the user's PW to the DB. Because it is one-way (you cannot easily get the original value back from the hash), this prevents someone like a janitor or customer service rep from being able to see the actual passwords in the database.
Imports System.Security.Cryptography
Imports System.Text
Shared Function GetHash(theInput As String) As String
Using hasher As MD5 = MD5.Create() ' create hash object
' Convert to byte array and get hash
Dim dbytes As Byte() =
hasher.ComputeHash(Encoding.UTF8.GetBytes(theInput))
' sb to create string from bytes
Dim sBuilder As New StringBuilder()
' convert byte data to hex string
For n As Integer = 0 To dbytes.Length - 1
sBuilder.Append(dbytes(n).ToString("X2"))
Next n
Return sBuilder.ToString()
End Using
End Function
Depending on how you want to save it, rather than a using StringBuilder to create a hex string, you can use Convert.ToBase64String():
Return Convert.ToBase64String(dbytes)
' MyWeakPassword hashed:
' to hex: DB28F1BE20A407398171295DD0D191E2
' to Base64: 2yjxviCkBzmBcSld0NGR4g==
Hashing should be done with salt. This is data added to the hash to make the result less predictable (there are dictionaries of the hashed results of common PW such as "password"; salt changes the outcome):
Shared Function GetHash(theInput As String, theSalt As String) As String
...
hasher.ComputeHash(Encoding.UTF8.GetBytes(theInput & theSalt))
Salt should be created using the Cryptographic random number generator as shown in the SHA Version. Convert the salt to text (hex or Base64) then combine with the PW to get the PW hash.
To check/compare a user's entry, simply hash the input and compare it to the hash stored in the database, using the same Salt (which means the Salt needs to be saved):
Shared Function CheckHash(hashedStr As String, newInput As String) As Boolean
' get the hash value of user input:
Dim newHash As String = GetHash(newInput & dbSalt)
' return comparison
Return String.Compare(newHash, hashedStr, InvariantCultureIgnoreCase)
End Function
As written, the GetHash function is intended to be used from something like a CryptoTools Class. Since it is Shared/Static the class need not be instanced:
thisHash = CryptoTools.GetHash(strToHash)
Note: Hashing is case sensitive, so foobar will result in a different hash than FooBar or FOOBAR. To create a case insensitive system, convert the original string (such as a password) to lowercase before you compute the MD5 hash value to be saved, and do the same for the value they later enter:
' ToLowerInvariant allows for foreign char sets
Dim str As String = PWTextBox.Text.ToLowerInvariant
If CheckHash(dbHashedValue, str) Then
' okie dokie
Else
' failed
End If
MD5 Convertion
Dim [source] As String = password_text_box.text
Using md5Hash As MD5 = MD5.Create()
Dim hash As String = GetMd5Hash(md5Hash, source)
2, Insert Name and hash into database
3, Validation
During login take MD5 of password again
run sql query
Select name,password from table where Login ='" & username & "' and
Password ='" & md5(user input pass) & "'
if dreader returns value , then valid login else invalid login
Private Function GetHash(strToHash As String) As String
Dim md5Obj As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strToHash)
bytesToHash = md5Obj.ComputeHash(bytesToHash)
Dim strResult As New StringBuilder
For Each b As Byte In bytesToHash
strResult.Append(b.ToString("x2"))
Next
Return strResult.ToString
End Function
This would be my solution:
Public Sub _Enkripsi()
Dim _DES As New TripleDESCryptoServiceProvider()
Dim _HashMD5 As New MD5CryptoServiceProvider()
_DES.Key = _HashMD5.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(PasswordTextBox.Text))
_DES.Mode = CipherMode.ECB
Dim _DESEncrypt As ICryptoTransform = _DES.CreateEncryptor()
Dim _Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(PasswordTextBox.Text)
_Password = Convert.ToBase64String(_DESEncrypt.TransformFinalBlock(_Buffer, 0, _Buffer.Length))
End Sub
Convert String to MD5 Function for Visual Studio Basic 2022
Imports System.Security.Cryptography
Imports System.Text
Function CovertToMD5(retVal As String) As String
Using MD5 = System.Security.Cryptography.MD5.Create()
Return BitConverter.ToString(MD5.ComputeHash(Encoding.Default.GetBytes(retVal))).Replace("-", String.Empty)
End Using
End Function
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.
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