如何生成加密安全随机数以用于不记名令牌?

How do I generate a cryptographically secure random number to use for bearer tokens?

我想生成一个安全随机数以用于 vapor 中的不记名令牌swift。

我看过OpenCrypto,但是好像不能生成随机数。

我该怎么做?

你可能想看看 SecRandomCopyBytes(_:_:_:):

来自Apple documentation

Generates an array of cryptographically secure random bytes.

var bytes = [Int8](repeating: 0, count: 10)
let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)

if status == errSecSuccess { // Always test the status.
    print(bytes)
    // Prints something different every time you run.
}

一般来说(但请继续阅读),您需要为此使用 SystemRandomNumberGenerator。作为 documented:

SystemRandomNumberGenerator is automatically seeded, is safe to use in multiple threads, and uses a cryptographically secure algorithm whenever possible.

“只要可能”可能会让您暂停,具体取决于部署方式。如果它在平台枚举列表中,您可以检查它们是否使用 CSPRNG。 “几乎”(见下文)所有当前平台都这样做:

  • Apple platforms use arc4random_buf(3).

  • Linux platforms use getrandom(2) when available; otherwise, they read from /dev/urandom.

  • Windows uses BCryptGenRandom.

在 Linux 上,getrandom 明确适用于加密目的,如果它还不能提供良好的熵则阻止。请参阅 source 了解其实现。具体来说,如果熵池还没有初始化,会阻塞:

if (!(flags & GRND_INSECURE) && !crng_ready()) {
    if (flags & GRND_NONBLOCK)
        return -EAGAIN;
    ret = wait_for_random_bytes();
    if (unlikely(ret))
        return ret;
}

在没有 getrandom 的系统上,我相信 SystemRandomNumberGenerator 使用的 swift_stdlib_random 在初始化之前可能会读取 /dev/urandom。这是一种罕见的情况(通常是在启动后立即发生,尽管可能是由于其他进程快速消耗了熵),但它可以降低值的随机性。在目前支持的 Swift 平台中,我相信这只会影响 CentOS 7。

在 Windows 上,BCryptGenRandom 被记录为适用于加密随机数:

The default random number provider implements an algorithm for generating random numbers that complies with the NIST SP800-90 standard, specifically the CTR_DRBG portion of that standard.

SP800-90 涵盖算法和熵要求。

对于 Vapor,您可以像这样生成令牌:

[UInt8].random(count: 32).base64

这将以加密方式安全使用。您可以像 this repo

中那样使用它