.NET - Computing SHA512 with SHA512Managed - Why two "==" when converting to string? - vb.net

For some reason everytime i compute a sha512 hash and convert it to a string, the two last characters are ==. Any idea why?
Function GetSHA512FromStringAsString(ByVal strdata As String)
Dim data As Byte() = StringToByte(strdata)
Dim result() As Byte
Dim shaM As New SHA512Managed()
result = shaM.ComputeHash(data)
Return ByteToString(result)
End Function
Function ByteToString(ByVal dBytes() As Byte)
Dim strText = Convert.ToBase64String(dBytes)
Return strText
End Function
Thanks!

Base64 strings can end in = or == based on the number of bytes being encoded. See http://en.wikipedia.org/wiki/Base64#Padding

It's the Base64 padding you see: Base64 transforms groups of 4 bytes in 3 bytes, which means that the last encoded group will not always be complete - depending on the length of the input string it will contain 1, 2 or 3 bytes. This is solved by padding, and the == you see here is caused by having just 1 used byte in the last encoded group of 3.
The full explanation can be found on Wikipedia

Related

VB Hex to DocX Object

I have a selection of docx files stored as blob data in hexadecimal, I need to retrieve these so I can access the text within.
So far, I have converted the hex to string format with the following:
Dim blob = BLOB DATA
Dim con As String = String.Empty
For x = 2 To st.Length - 2 Step 2
con &= ChrW(CInt("&H" & st.Substring(x, 2)))
Next
However, if I then save the output from this as a .docx the file will not open because it is 'corrupt'. I presume that is why when I load this string into a memorystream and then try and use Novacode.DocX.Load(memoryStream) it gives me a similar corruption error.
I have tried splitting to byte array in two fashions, both give me different results.
System.Text.Encoding.Default.GetBytes(hex)
I have also tried.
Public Function HexToByteArray(hex As String) As Byte()
Dim upperBound As Integer = hex.Length \ 2
If hex.Length Mod 2 = 0 Then
upperBound -= 1
Else
hex = "0" & hex
End If
Dim bytes(upperBound) As Byte
For i As Integer = 2 To upperBound
bytes(i) = Convert.ToByte(hex.Substring(i * 2, 2), 16)
Next
Return bytes
End Function
I then tried converting them both to a memory stream and using them to create a DocX object like so:
Dim doc As DocX = DocX.Load(New MemoryStream(bytes))
docx is not a text format, it's a binary format. Thus, converting it to a string is just plain wrong. Your end result needs to be a byte array.
Knowing that, your problem can be split into two simpler problems:
Split your hex string into strings of two characters each. See this SO question for details (or keep your existing loop, which is perfectly fine):
How to split a string by x amount of characters
Convert those "small" strings, which contain the hexadecimal representation of a byte, into bytes. See this SO question for details:
How do I convert a Hexidecimal string to a Byte Array?
Combining those two solutions is left as an exercise to the reader. We don't want to spoil all the fun or ruin the learning experience. ;-)

Convert string of byte array back to original string in vb.net

I have a plain text string that I'm converting to a byte array and then to a string and storing in a database.
Here is how I'm doing it:
Dim b As Byte() = System.Text.Encoding.UTF8.GetBytes("Hello")
Dim s As String = BitConverter.ToString(b).Replace("-", "")
Afterwards I store the value of s (which is "48656C6C6F") into a database.
Later on, I want to retrieve this value from the database and convert it back to "Hello". How would I do that?
You can call the following function with your hex string and get "Hello" returned to you. Note that the function doesn't validate the input, you would need to add validation unless you can be sure the input is valid.
Private Function HexToString(ByVal hex As String) As String
Dim result As String = ""
For i As integer = 0 To hex.Length - 1 Step 2
Dim num As Integer = Convert.ToInt32(hex.Substring(i, 2), 16)
result &= Chr(num)
Next
Return result
End Function
James Thorpe points out in his comment that it would be more appropriate to use Encoding.UTF8.GetString to convert back to a string as that is the reverse of the method used to create the hex string in the first place. I agree, but as my original answer was already accepted, I hesitate to change it, so I am adding an alternative version. The note about validation of input being skipped still applies.
Private Function HexToString(ByVal hex As String) As String
Dim bytes(hex.Length \ 2 - 1) As Byte
For i As Integer = 0 To hex.Length - 1 Step 2
bytes(i \ 2) = Byte.Parse(hex.Substring(i, 2), System.Globalization.NumberStyles.HexNumber)
Next
Return System.Text.Encoding.UTF8.GetString(bytes)
End Function

Trim/Truncate string to a maximum number of bytes

I am working with some MP3s in ASP.NET coding in VB and have come across a couple of problems with the ID3 tag length limits.
It seems that most tags have a limit of 30 bytes.
I know how to get the length in bytes of a string, but want to be able to trim a string to a maximum of 30 bytes, minus however many bytes ... is, so that where needed I can trim a title to "this is part of a title..." where the total is <= 30 bytes.
EDIT:
For clarification;
The titles are string values, that must be <= 30 bytes.
Using ServiceStack I am able to easily convert my string to a byte array:
Dim bytes as byte() = "This title".ToAsciiBytes()
Then I get the length in bytes:
Dim L as integer = bytes.length()
What I need next is to grab just the first 30 bytes and convert back to a string (which is simply bytes.FromAsciiBytes())
Public Function FormatTitle(ByVal title As String) As String
Dim byte() As Byte = Encoding.ASCII.GetBytes(title)
If bytes.Length > 30 Then
Dim dot As Byte = 46 'ascii value of "."
bytes(27) = dot
bytes(28) = dot
bytes(29) = dot
Array.Resize(bytes, 30)
End If
Return Encoding.ASCII.GetString(bytes)
End Function

encrypt a string using SHA512

Here 's my code and I have no idea why it produces a weird code in the console
(output is "b5?2???p?????'5???.?H???Kun???a??\??d??+\??%??A)?_???j?" without the quotes)
Private Sub TestSHA512()
Dim key As String = "635357773463315343"
Dim pass As String = "somepasswd"
Dim enc As System.Text.Encoding = New System.Text.ASCIIEncoding
Dim keyBytes() As Byte = enc.GetBytes(key)
Dim passBytes() As Byte = enc.GetBytes(pass)
Dim SHA As New HMACSHA512(keyBytes)
Dim resultBytes() As Byte = SHA.ComputeHash(passBytes)
Console.WriteLine(enc.GetString(resultBytes))
Console.WriteLine(enc.GetString(SHA.Hash)) 'same...
End Sub
First, SHA512 is a hash algorithm, not an encryption scheme, so if you're trying to encrypt then SHA512 isn't the way to do it. You'd need to look at an encryption class, such as AesManaged.
ComputeHash gives you the computed hash as a byte array. You're using ASCIIEncoding.GetString to convert that into a string, but not every byte is a printable ASCII character. That's why you're seeing the ??? characters in your console output.
If you're asking how to display the hash output as a printable string, use Convert.ToBase64String, which will convert the byte array into a string using base64 encoding. If you were expecting it in hexadecimal, you can loop through the byte array and print the Hex() value of each byte.

Converting String to String of Hex and vice-versa in Vb.Net

I need to convert a String of totally random characters in something i can read back!
My idea is:
Example String: hi
h (Ascii) -> 68 (hex)
i (Ascii) -> 69 (hex)
So converting hi i must have 6869
My value is now in Base64 (i got it with a Convert.ToBase64String()), is this "ascii to hex" conversion correct? In base64 i have value like "4kIw0ueWC/+c=" but i need characters only, special characters can mess my system
The vb.net Convert can only translate to base64 string :(
edit: This is my final solution:
i got the base64 string inside my enc variable and converted it first in ASCII then in corrispondent Hex using:
Dim bytes As Byte() = System.Text.Encoding.ASCII.GetBytes(enc)
Dim hex As String = BitConverter.ToString(bytes).Replace("-", String.Empty)
After that i reversed this with:
Dim b((input.Length \ 2) - 1) As Byte
For i As Int32 = 0 To b.GetUpperBound(0)
b(i) = Byte.Parse(input.Substring(i * 2, 2), Globalization.NumberStyles.HexNumber)
Next i
Dim enc As New System.Text.ASCIIEncoding()
result = enc.GetString(b)
After all this i got back my base64string and converted one last time with Convert.FromBase64String(result)
Done! Thanks for the hint :)
First get Byte() from your base64 string:
Dim data = Convert.FromBase64String(inputString)
Then use BitConverter:
String hex = BitConverter.ToString(data)