いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-246 (セキュリティ的に安全な乱数を取得する)(crypto/rand, Reader)

概要

cryptoパッケージの下の処理を利用しようとするときなどに、乱数が必要になるときがあります。

また、セキュリティ的に安全な乱数を取得したい場合もあります。

そのようなときに Go では、crypto/rand の中に rand.Reader が存在していますので、これを利用すると取得できます。

rand package - crypto/rand - Go Packages

説明の部分には以下のように記載されています。以下引用

On Linux, FreeBSD, Dragonfly and Solaris, Reader uses getrandom(2) if available, /dev/urandom otherwise. On OpenBSD and macOS, Reader uses getentropy(2). On other Unix-like systems, Reader reads from /dev/urandom. On Windows systems, Reader uses the RtlGenRandom API. On Wasm, Reader uses the Web Crypto API.

Linux、FreeBSD、Dragonfly、Solaris では、Reader は getrandom(2) があればそれを使い、なければ /dev/urandom を使用します。OpenBSD と macOS では、Reader は getentropy(2) を使用します。他の Unix 系システムでは、Reader は /dev/urandom から読み込む。Windows システムでは、Reader は RtlGenRandom API を使用します。Wasm では、Reader は Web Crypto API を使用します。 (by DeepL 先生)

サンプル

package rand

import (
    "crypto/rand"
    "encoding/hex"
    "io"

    "github.com/devlights/gomy/iter"
    "github.com/devlights/gomy/output"
)

// RandomBytes -- crypto/rand.Reader を用いてセキュリティ的に安全な乱数を生成するサンプルです.
//
// # REFERENCES
//   - https://pkg.go.dev/crypto/rand@go1.19#pkg-variables
func RandomBytes() error {
    var (
        r = rand.Reader
    )

    for range iter.Range(10) {
        var (
            b   = make([]byte, 32)
            err error
        )

        _, err = io.ReadFull(r, b)
        if err != nil {
            return err
        }

        output.Stdoutl("[Crypto][rand.Reader]", hex.EncodeToString(b))
    }

    return nil
}

以下、実行結果です。

$ task
task: [run] go run . -onetime

ENTER EXAMPLE NAME: crypto_random_bytes

[Name] "crypto_random_bytes"
[Crypto][rand.Reader] 373ae09da732fea659649ab02e32f557fb07921e30a63c7c26b3f300d0d78004
[Crypto][rand.Reader] ff007c3ff4fd74208a08cf03c91d22532598d181fc8c254ce1c5e9a07f529e7d
[Crypto][rand.Reader] 12ef90cdd0b9af7367036a28123cf3bd50302a6037a74a87ee2af95126628621
[Crypto][rand.Reader] 2c1b3eba3c9729fe249d3b829d93a871a506df53e680539e8a56b293f59e9a1a
[Crypto][rand.Reader] 91170b314d9c1970ece1842e5e71e6d82acbda4e29395a3e72a4b7fd08aa8e5d
[Crypto][rand.Reader] a27a3f071fce398f3d85420401d7066c23ee60ce24406b7d4a262d7acae1411b
[Crypto][rand.Reader] d054c9b8ef49df9716592287754d7d53e55366aa1c1d0213cbc650e15a533f11
[Crypto][rand.Reader] 99246133e72cd40b65a0789fd2caaea6b5b76aade8c73a1e809434446bd6a93e
[Crypto][rand.Reader] 12ee9965b8a7688d583c207f88657c659a8effe9aaddb2aef3c25f516ef58f13
[Crypto][rand.Reader] 489d999227a1137dc7e5f1b512e461e8f28efcbec6f8a1cf089e24c20959dae1


[Elapsed] 84.05µs

当然ですが、実行するたびに異なる値が得られます。

参考情報

rand package - crypto/rand - Go Packages

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。