DEV Community

Masui Masanori
Masui Masanori

Posted on

4 3

[Go] Try HMAC-SHA512 implementation

#go

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.

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
}
Enter fullscreen mode Exit fullscreen mode

Examples

main.go

package main

import (
    "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)
}
Enter fullscreen mode Exit fullscreen mode

hmacSHA512Hasher.go

package main

const 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
}
Enter fullscreen mode Exit fullscreen mode

Result

8F9909C45E601A31A2E6949FE6E4C739ADE74F3A0A5F9489D4E5F8BC5B71C08C998C78E14AB4C524E884A308E1E4B9902E7E76D9E1328E5A603B7DFA42604D74
8F9909C45E601A31A2E6949FE6E4C739ADE74F3A0A5F9489D4E5F8BC5B71C08C998C78E14AB4C524E884A308E1E4B9902E7E76D9E1328E5A603B7DFA42604D74
Enter fullscreen mode Exit fullscreen mode

Resources

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay