🔑
Goで暗号論的擬似乱数を生成する
はじめに
この記事は「Qiita Advent Calendar 2023 Go言語」の23日目の記事です。
ゴール
Go言語で署名に利用する鍵を生成したいケースがあったので、その方法をまとめます。
Goの乱数生成
Goの乱数生成に関する標準パッケージには次の2つがあります
math/rand
擬似乱数生成器。
math/rand
は、初期化のためのSeedによって、生成される乱数が決まります。(https://golang.org/src/math/rand/rng.go)
Seed値に対応した値を返すため、乱数を再現することが可能です。そのため、生成されるランダム値が予測されやすく暗号系技術での使用には適しません。
crypto/rand
暗号論的擬似乱数生成器。
io.Readerインターフェイスを利用してランダムなバイト列を取り出すことができます。生成されるランダム値を予測するのが困難なので、秘密鍵の生成などに用いることができます。
今回のケースでは予測困難性が求められるので、crypto/rand
を利用して乱数を生成してみます。
64バイトの key を生成する
crypto/rand
を利用して64バイトの key を生成するサンプルコードです。
func main() string {
randBytes := make([]byte, 64)
_, err := io.ReadFull(rand.Reader, randBytes)
if err != nil {
panic(err)
}
// バイト列のデータをBase64でエンコーディングし、文字列を生成
return base64.RawURLEncoding.WithPadding(base64.NoPadding).EncodeToString(randBytes)
}
- io.ReadFull(rand.Reader, randBytes)でランダムなバイト配列を取得できます。
- エンコーディングは encoding/base64 を利用できます。
サンプルでは、RawURLEncoding
を使用してURL Safeなエンコーディングを行うようしています。
まとめ
「パスワード・セッションIDの生成」や「暗号化に必要なランダムなバイト列の生成」など、ランダムかつ予測困難性が求められる場合はcrypto/rand
を利用して生成することができます。
Discussion