Generating the SHA hash of a string using golang - hash

Can someone show me a working example of how to generate a SHA hash of a string that I have, say myPassword := "beautiful", using Go?

An example :
import (
"crypto/sha1"
"encoding/base64"
)
func (ms *MapServer) storee(bv []byte) {
hasher := sha1.New()
hasher.Write(bv)
sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
...
}
In this example I make a sha from a byte array. You can get the byte array using
bv := []byte(myPassword)
Of course you don't need to encode it in base64 if you don't have to : you may use the raw byte array returned by the Sum function.
There seems to be some little confusion in comments below. So let's clarify for next users the best practices on conversions to strings:
you never store a SHA as a string in a database, but as raw bytes
when you want to display a SHA to a user, a common way is Hexadecimal
when you want a string representation because it must fit in an URL or in a filename, the usual solution is Base64, which is more compact

Go By Example has a page on sha1 hashing.
package main
import (
"fmt"
"crypto/sha1"
"encoding/hex"
)
func main() {
s := "sha1 this string"
h := sha1.New()
h.Write([]byte(s))
sha1_hash := hex.EncodeToString(h.Sum(nil))
fmt.Println(s, sha1_hash)
}
You can run this example on play.golang.org

The package documentation at http://golang.org/pkg/crypto/sha1/ does have an example that demonstrates this. It's stated as an example of the New function, but it's the only example on the page and it has a link right near the top of the page so it is worth looking at. The complete example is,
Code:
h := sha1.New()
io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.")
fmt.Printf("% x", h.Sum(nil))
Output:
59 7f 6a 54 00 10 f9 4c 15 d7 18 06 a9 9a 2c 87 10 e7 47 bd

You can actually do this in a much more concise and idiomatic manner:
// Assuming 'r' is set to some inbound net/http request
form_value := []byte(r.PostFormValue("login_password"))
sha1_hash := fmt.Sprintf("%x", sha1.Sum(form_value))
// Then output optionally, to test
fmt.Println(sha1_hash)
In this trivial example of a http.Request POST containing a login_password field, it is worth noting that fmt.Sprintf() called with %x converted the hash value to hex without having to include an import "encoding/hex" declaration.
( We used fmt.Sprintf() as opposed to fmt.Printf() as we were outputting a string to a variable assignment, not an io.Writer interface. )
Also of reference, is that the sha1.Sum() function verbosely instantiates in the same manner as the sha1.New() definition:
func New() hash.Hash {
d := new(digest)
d.Reset()
return d
}
func Sum(data []byte) [Size]byte {
var d digest
d.Reset()
d.Write(data)
return d.checkSum()
}
This holds true ( at least at the time of posting ) for the Sha library variants in Golang's standard crypto set, such as Sha512.
Lastly, if one wanted to, they could follow Golang's [to]String() implementation with something like func (h hash.Hash) String() string {...} to encapsulate the process.
That is most likely beyond the desired scope of the original question.

h := sha1.New()
h.Write(content)
sha := h.Sum(nil) // "sha" is uint8 type, encoded in base16
shaStr := hex.EncodeToString(sha) // String representation
fmt.Printf("%x\n", sha)
fmt.Println(shaStr)

Here's some good examples:
http://golang.org/src/pkg/crypto/hmac/hmac_test.go
http://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/#go
The second example targets sha256, to do sha1 hexadecimal you'd do:
// Calculate the hexadecimal HMAC SHA1 of requestDate using sKey
key := []byte(c.SKey)
h := hmac.New(sha1.New, key)
h.Write([]byte(requestDate))
hmacString := hex.EncodeToString(h.Sum(nil))
(from https://github.com/soniah/dnsmadeeasy)

Here is a function you could use to generate a SHA1 hash:
// SHA1 hashes using sha1 algorithm
func SHA1(text string) string {
algorithm := sha1.New()
algorithm.Write([]byte(text))
return hex.EncodeToString(algorithm.Sum(nil))
}
I put together a group of those utility hash functions here: https://github.com/shomali11/util
You will find FNV32, FNV32a, FNV64, FNV65a, MD5, SHA1, SHA256 and SHA512

// Get sha1 from string
func Hashstr(Txt string) string {
h := sha1.New()
h.Write([]byte(Txt))
bs := h.Sum(nil)
sh:= string(fmt.Sprintf("%x\n", bs))
return sh
}

Related

How to make a multiline string value from MongoDB's bson.M in Golang?

I'm creating a telegram bot using Golang, and I need some advice on how to retrieve a multiline string value from function in Golang, that has same logic like this Python string
answer = """1 John 95
2 Sam 89
3 Mike 72"""
I have a function that creates a MongoDB request that gets me a data in bson.M datatype. And after that I need to send this queried data to a user as a single string value using this form:
msg := tgbotapi.NewMessage(
update.Message.Chat_ID,
answer,
)
bot.Send(msg)
I don't really know how to transform this bson.M data into a single multiline string.
bson.M response that I get from the function:
[map[_id:ObjectID("62a4acf2a494a2814238c6e1") bandMember:John name:School12 points:95]
map[_id:ObjectID("62a4acf2a494a2814238c6e2") bandMember:Sam name:School15 points:89]
map[_id:ObjectID("62a4acf2a494a2814238c6e3") bandMember:Mike name:School7 points:72]]
And I have to insert it in a string variable of "answer" (see above example)
Thanks in advance!
Loop through the documents and sprintf a line for each document. Join the lines with newline to get the final result.
var lines []string
for i, m := range data {
lines = append(lines, fmt.Sprintf("%d %s %d", i+1, m["bandMember"], m["points"]))
}
result := strings.Join(lines, "\n")

Convert Hexadecimal to Base64 in Authotkey

I just found this code written in python to convert Hexadecimal to Base64:
import codecs
hex = "10000000000002ae"
b64 = codecs.encode(codecs.decode(hex, 'hex'), 'base64').decode()
So, Is it possible to find same working one but in Autohotkey?
There many implementations, some very fast and some more simple. You can take a look at libcrypt.ahk for many encoding and encryption algorithms including Hexadecimal and Base64.
If you do use it, you'll want to look at LC_Hex2Bin() and LC_Base64_Encode(). Examples are available too. You will likely want this libcrypt.ahk file in particular.
Example
#Include libcrypt.ahk
Hex := "48656c6c6f20576f726c642100"
len := LC_Hex2Bin(Bin, Hex)
LC_Base64_Encode(base64, Bin, len)
MsgBox % base64
Or as single function
#Include libcrypt.ahk
MsgBox % hexstring2base64("48656c6c6f20576f726c642100")
hexstring2base64(hex_string) {
len := LC_Hex2Bin(Bin, hex_string)
LC_Base64_Encode(base64, Bin, len)
return base64
}

Find a string for which hash() starts with 0000

I've got a task from my professor and unfortunately I'm really confused.
The task:
Find a string D1 for which hash(D1) contains 4 first bytes equal 0.
So it should look like "0000....."
As I know we cannot just decrypt a hash, and checking them one by one is kind of pointless work.
I've got a task from my professor...
Find a string D1 for which hash(D1) contains 4 first bytes equal 0. So it should look like "0000....."
As I know we cannot just decrypt a hash, and checking them one by one is kind of pointless work.
In this case it seem like the work is not really "pointless." Rather, you are doing this work because your professor asked you to do it.
Some commenters have mentioned that you could look at the bitcoin blockchain as a source of hashes, but this will only work if your hash of interest is the same one use by bitcoin (double-SHA256!)
The easiest way to figure this out in general is just to brute force it:
Pseudo-code a la python
for x in range(10*2**32): # Any number bigger than about 4 billion should work
x_str = str(x) # Any old method to generate some bytes to hash should work
x_bytes = x_str.encode('utf-8')
hash_bytes = hash(x_bytes) # assuming hash() returns bytes
if hash_bytes[0:4] == b'\x00\x00\x00\x00':
print("Found string: {}".format(x_str))
break
I wrote a short python3 script, which repeatedly tries hashing random values until it finds a value whose SHA256 hash has four leading zero bytes:
import secrets
import hashlib
while(True):
p=secrets.token_bytes(64)
h=hashlib.sha256(p).hexdigest()
if(h[0:8]=='00000000'): break
print('SHA256(' + p.hex() + ')=' + h)
After running for a few minutes (on my ancient Dell laptop), it found a value whose SHA256 hash has four leading zero bytes:
SHA256(21368dc16afcb779fdd9afd57168b660b4ed786872ad55cb8355bdeb4ae3b8c9891606dc35d9f17c44219d8ea778d1ee3590b3eb3938a774b2cadc558bdfc8d4)=000000007b3038e968377f887a043c7dc216961c22f8776bbf66599acd78abf6
The following command-line command verifies this result:
echo -n '21368dc16afcb779fdd9afd57168b660b4ed786872ad55cb8355bdeb4ae3b8c9891606dc35d9f17c44219d8ea778d1ee3590b3eb3938a774b2cadc558bdfc8d4' | xxd -r -p | sha256sum
As expected, this produces:
000000007b3038e968377f887a043c7dc216961c22f8776bbf66599acd78abf6
Edit 5/8/21
Optimized version of the script, based on my conversation with kelalaka in the comments below.
import secrets
import hashlib
N=0
p=secrets.token_bytes(32)
while(True):
h=hashlib.sha256(p).digest()
N+=1
if(h.hex()[0:8]=='0'*8): break
p=h
print('SHA256(' + p.hex() + ')=' + h.hex())
print('N=' + str(N))
Instead of generating a new random number in each iteration of the loop to use as the input to the hash function, this version of the script uses the output of the hash function from the previous iteration as the input to the hash function in the current iteration. On my system, this quadruples the number of iterations per second. It found a match in 1483279719 iterations in a little over 20 minutes:
$ time python3 findhash2.py
SHA256(69def040a417caa422dff20e544e0664cb501d48d50b32e189fba5c8fc2998e1)=00000000d0d49aaaf9f1e5865c8afc40aab36354bc51764ee2f3ba656bd7c187
N=1483279719
real 20m47.445s
user 20m46.126s
sys 0m0.088s
The sha256 hash of the string $Eo is 0000958bc4dc132ad12abd158073204d838c02b3d580a9947679a6
This was found using the code below which restricts the string to only UTF8 keyboard characters. It cycles through the hashes of each 1 character string (technically it hashes bytes, not strings), then each 2 character string, then each 3 character string, then each 4 character string (it never had to go to 4 characters, so I'm not 100% sure the math for that part of the function is correct).
The 'limit" value is included to prevent the code from running forever in case a match is not found. This ended up not being necessary as a match was found in 29970 iterations and the execution time was nearly instantaneous.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from hashlib import sha256
utf8_chars = list(range(0x21,0x7f))
def make_str(attempt):
if attempt < 94:
c0 = [attempt%94]
elif attempt >= 94 and attempt < 8836:
c2 = attempt//94
c1 = attempt%94
c0 = [c2,c1]
elif attempt >= 8836 and attempt < 830584:
c3 = attempt//8836
c2 = (attempt-8836*c3)//94
c1 = attempt%94
c0 = [c3,c2,c1]
elif attempt >= 830584 and attempt < 78074896:
c4 = attempt//830584
c3 = (attempt-830584*c4)//8836
c2 = ((attempt-830584*c4)-8836*c3)//94
c1 = attempt%94
c0 = [c4,c3,c2,c1]
return bytes([utf8_chars[i] for i in c0])
target = '0000'
limit = 1200000
attempt = 0
hash_value = sha256()
hash_value.update(make_str(attempt))
while hash_value.hexdigest()[0:4] != target and attempt <= limit:
hash_value = sha256()
attempt += 1
hash_value.update(make_str(attempt))
t = ''.join([chr(i) for i in make_str(attempt)])
print([t, attempt])

generating MD5 hash of a text with C#

I understand that System.Security.Cryptography has a MD5 hashing method in MD5.ComputeHash. However, the method takes and returns bytes. I don't understand how to work with this method using String key and hashes. I try to work around by doing this,
var hash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(#"text".ToCharArray()));
foreach(byte h in hash)
{
Console.Write((char)h);
}
However the resulting output is gibberish string. For comparison, in this website, entering "text" will result in "1cb251ec0d568de6a929b520c4aed8d1"
writing this code will give the same result as the website:
var hash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(#"text".ToCharArray()));
foreach(byte h in hash)
{
Console.Write(h.ToString("x2"));
}
The trick is to print each byte as 2 hexadecimal digits (hence x2)

Cryptographic hash (sha1 or md5) of data given as a string in Mathematica

The sha1 hash of "abc" is
a9993e364706816aba3e25717850c26c9cd0d89d
The only way to get Mathematica to tell you that with its Hash function is
Hash[abc, "SHA"] // IntegerString[#, 16]&
(The IntegerString thing is just to output it in hex like most implementations do.)
Note that
Hash["abc", "SHA"]
gives the hash of "\"abc\"" -- not what you want!
In fact, the only reason we could get the correct hash of "abc" was because the Mathematica representation of the symbol abc happens to be the string "abc".
For the vast majority of strings, this will not be the case.
So how do you take the hash of an arbitrary string in Mathematica?
You can do it less kludgily by using StringToStream and the fact that FileHash can take an input stream as an argument. Then your sha1 function becomes:
sha1[s_String] := Module[{stream = StringToStream[s], hash},
hash = FileHash[stream,"SHA"];
Close[stream];
hash]
Here's a kludge that works. Write the string to a temp file and use FileHash:
sha1[s_String] := Module[{stream, file, hash},
stream = OpenWrite[];
WriteString[stream, s];
file = Close[stream];
hash = FileHash[file, "SHA"];
DeleteFile[file];
hash]
You might also want to define
hex = IntegerString[#, 16]&;
and return hex#hash in the above function.