June 17, 2022 03:30 pm GMT
Original Link: https://dev.to/masanori_msl/go-try-hmac-sha512-implementation-2pij
[Go] Try HMAC-SHA512 implementation
Intro
This time, I will try implementing HMAC-SHA512.
I will use the SHA-512 function what I wrote last time.
Secret Key
HMAC needs a key and a message to get a hash value.
The key has several features.
- It is shared only by the sender and the receiver
- It can be of any length
- If its length is shorter than the byte-length of the hash function, it is first filled with zeros to make it that length
- If its length is longer than the byte-length of the hash function, it will be hashed first
It seems that "PasswordHasher" also uses the password(message) as a key.
- aspnetcore/PasswordHasher.cs - dotnet/aspnetcore - GitHub
- aspnetcore/ManagedPbkdf2Provider.cs - dotnet/aspnetcore - GitHub
Update SHA-512
Last time, I returned the result as a string value.
But I want to get the value as byte array to append the key, so I change the SHA-512 function.
sha512Hasher.go
...func Hash(inputValues []byte) []byte { formattedMessage := formatInput(inputValues) computed := compute(formattedMessage) return computed}...func compute(messages []byte) []byte {... // get H[N] var results []byte for _, h := range H { b := make([]byte, 8) binary.BigEndian.PutUint64(b, h) results = append(results, b...) } return results}
- How can I convert an int64 into a byte array in go? - StackOverflow
- Concatenate 2 slices in golang - StackOverflow
Examples
main.go
package mainimport ( "crypto/hmac" "crypto/sha512" "fmt" "log")func main() { inputData := []byte("hello") hmacSHA512Results := HashHMACSHA512(inputData, inputData) var hresult string for _, r := range hmacSHA512Results { hresult += fmt.Sprintf("%02X", r) } log.Println(hresult) h := hmac.New(sha512.New, inputData) h.Write(inputData) results := h.Sum(nil) var result string for _, r := range results { result += fmt.Sprintf("%02X", r) } log.Println(result)}
hmacSHA512Hasher.go
package mainconst byteLength int = 128/* compute H(K XOR opad, H(K XOR ipad, text)) */func HashHMACSHA512(inputData, keyData []byte) []byte { formattedKey := formatKey(keyData) ipad := xorIPAD(formattedKey) // append the stream of input data to the result of (K XOR ipad) // and hash the value innerData := Hash(append(ipad, inputData...)) opad := xorOPAD(formattedKey) // append the H result to the result of (K XOR opad) // and hash the value return Hash(append(opad, innerData...))}func formatKey(keyData []byte) []byte { // If its length is longer than the byte-length, // it will be hashed first if len(keyData) >= byteLength { return Hash(keyData) } // If its length is shorter than the byte-length, // it is first filled with zeros to make it that length results := make([]byte, byteLength) copy(results, keyData) for i := len(keyData); i < byteLength; i++ { results[i] = 0x00 } return results}/* K XOR ipad(ipad = the byte 0x36 repeated B times) */func xorIPAD(k []byte) []byte { results := make([]byte, len(k)) for i, key := range k { results[i] = key ^ 0x36 } return results}/* K XOR opad(opad = the byte 0x5C repeated B times) */func xorOPAD(k []byte) []byte { results := make([]byte, len(k)) for i, key := range k { results[i] = key ^ 0x5C } return results}
Result
8F9909C45E601A31A2E6949FE6E4C739ADE74F3A0A5F9489D4E5F8BC5B71C08C998C78E14AB4C524E884A308E1E4B9902E7E76D9E1328E5A603B7DFA42604D748F9909C45E601A31A2E6949FE6E4C739ADE74F3A0A5F9489D4E5F8BC5B71C08C998C78E14AB4C524E884A308E1E4B9902E7E76D9E1328E5A603B7DFA42604D74
Resources
Original Link: https://dev.to/masanori_msl/go-try-hmac-sha512-implementation-2pij
Share this article:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To