技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

hmac【Go】

hmacとはハッシュメッセージ認証コードの略で、API認証に利用される、認証方式のことです。 クライアントからサーバーへ秘密情報を送信せずに認証できるメリットがあります。

クライアントから送られるハッシュ化された情報を、
クライアントから送られてきたキーと同じキーに紐づけられたデータを使用して、
サーバーでも再現し、情報が一致することをもって、認証成功とします。

処理の手順は大方定式化されているため、
その手順を覚えてしまうのが良いようです。

下記例では、サーバーの処理を関数に見立てて、
その関数内での処理結果と、main関数での処理結果を照合する処理を記載しています。

var DB = map[string]string{    // サーバーが持っている情報と仮定したmap
    "User1Key": "User1Secret",
    "User2Key": "User2Secret",
}

func Server(apiKey, sign string, data []byte) {
    apiSecret := DB[apiKey]
    h := hmac.New(sha256.New, []byte(apiSecret))
    h.Write(data)
    expectedHMAC := hex.EncodeToString(h.Sum(nil))    // byte配列を返すSum()を使い(足す物はないので引数はnil)、stringにエンコードし、認証情報を生成。byte配列はnilとの比較しかできないため、stringにエンコードする必要がある
    fmt.Println(sign == expectedHMAC)    // main関数から送られた情報との照合
}

func main() {
    const (
        apiKey    = "User1Key"
        apiSecret = "User1Secret"
    )
    h := hmac.New(sha256.New, []byte(apiSecret))    // sha256アルゴリズムでハッシュ化するhを生成し、apiSecretを鍵とする
    data := []byte("someData")
    h.Write(data)    // 必要な情報を書き込む
    sign := hex.EncodeToString(h.Sum(nil))    // byte配列を返すSum()を使い(足す物はないので引数はnil)、stringにエンコードし、認証情報を生成。byte配列はnilとの比較しかできないため、stringにエンコードする必要がある
    Server(apiKey, sign, data)    // サーバーへの送信に見立てた関数を実行
}


認証情報(sign)の生成には、タイムスタンプも合わせて利用されるケースがあります。