SessionId/身份验证令牌生成的最佳实践

发布于 2024-10-21 03:53:21 字数 307 浏览 4 评论 0 原文

我见过有人使用 UUID 来生成身份验证令牌。然而,在 RFC 4122 中指出

不要假设 UUID 很难猜测;不应该使用它们 作为安全功能(仅拥有即可授予的标识符 访问),例如。

我想知道 Java 和 .NET 中使用什么算法来生成 SessionId/AuthenticationToken。在具有高于平均安全需求的应用程序中,UUID 是否确实不适合这些目的?

I have seen people using UUID for authentication token generation. However, in RFC 4122 it is stated that

Do not assume that UUIDs are hard to guess; they should not be used
as security capabilities (identifiers whose mere possession grants
access), for example.

I was wondering, what algorithms are used for example in Java and .NET for SessionId/AuthenticationToken generation. Is UUID indeed unsuitable for these purposes in an application that has more than average security needs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

‖放下 2024-10-28 03:53:22

UUID 的生成是随机的,但是具有不良熵的随机意味着您最终会得到容易猜测的 UUID。如果您使用良好的随机数生成器,则可以生成可用于会话的 UUID。然而,问题在于 UUID 没有内置的重播预防、篡改、固定等功能,您必须自己处理这些问题(阅读:UUID其本身不应被视为有效的会话 ID)。也就是说,这里有一个很好的片段,说明如何使用 python 生成安全的 UUID

python 中的唯一会话 ID

UUID generation is random, but random with bad entropy means that you will end up with easy to guess UUIDs. If you use a good random number generator, you can generate UUIDs that can be used for sessions. The catch to this, however, is that UUIDs don't have built-in re-play prevention, tampering, fixation, etc., you have to handle that on your own (read: a UUID by itself shouldn't be considered a valid session ID by itself). That said, here's a good snippet for how you would generate a secure UUID using python:

Unique session id in python

南渊 2024-10-28 03:53:22

免责声明:我不是密码学家。


不要假设 UUID 很难猜测;例如,它们不应该被用作安全功能(仅拥有即可授予访问权限的标识符)。

虽然一般来说这是正确的,但还应该注意的是,某些系统使用加密的强伪随机数生成器生成 UUID(例如 Java):

公共静态UUID randomUUID()

用于检索类型 4(伪随机生成)UUID 的静态工厂。 UUID 是使用加密的强伪随机数生成器生成的。

退货
随机生成的 UUID

我想知道 Java 和 .NET 中使用什么算法来生成 SessionId/AuthenticationToken。

Tomcat 不使用 UUID 作为会话令牌,而是使用 SHA1PRNG 用于生成会话 ID 的安全随机生成器:

/**
 * The name of the algorithm to use to create instances of
 * {@link SecureRandom} which are used to generate session IDs. If no
 * algorithm is specified, SHA1PRNG is used. To use the platform default
 * (which may be SHA1PRNG), specify the empty string. If an invalid
 * algorithm and/or provider is specified the {@link SecureRandom} instances
 * will be created using the defaults. If that fails, the {@link
 * SecureRandom} instances will be created using platform defaults.
 */
private String secureRandomAlgorithm = "SHA1PRNG";

这只是默认值,您可以通过实现 org.apache 来提供自定义会话 ID 生成器.catalina.SessionIdGenerator 接口。

除了在会话 ID 中使用随机生成的字符串之外,标准实现还添加了 jvmRoute 到它生成的会话 ID:

此 Tomcat 实例的路由标识符。它将被添加到会话 ID 中,以允许负载均衡器进行无状态粘性路由。有关如何将 jvmRoute 包含在 id 中的详细信息取决于实现。请参阅默认行为的标准实现。

此处已经讨论了 SHA1PRNG 的优势。

UUID 是否确实不适合在具有高于平均安全需求的应用程序中实现这些目的?

Java UUID 几乎与 Tomcat 的默认会话 ID 生成器一样安全,后者生成 16 字节长的会话 ID:

Tomcat

/** Number of bytes in a session ID. Defaults to 16. */
private int sessionIdLength = 16;

OpenJDK 7 中的 java.util.UUID

public static UUID randomUUID() {
    SecureRandom ng = numberGenerator;
    if (ng == null) {
        numberGenerator = ng = new SecureRandom();
    }

    byte[] randomBytes = new byte[16];
    ng.nextBytes(randomBytes);
    randomBytes[6]  &= 0x0f;  /* clear version        */
    randomBytes[6]  |= 0x40;  /* set to version 4     */
    randomBytes[8]  &= 0x3f;  /* clear variant        */
    randomBytes[8]  |= 0x80;  /* set to IETF variant  */
    return new UUID(randomBytes);
}

但您可以将 Tomcat 的会话 ID 生成器配置为使用超过 16 个字节以提高安全性。

进一步阅读:

Disclaimer: I am not a cryptographer.


Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example.

While in general that is true, it should also be noted that some systems produce UUIDs using cryptographically strong pseudo random number generators (e.g. Java):

public static UUID randomUUID()

Static factory to retrieve a type 4 (pseudo randomly generated) UUID. The UUID is generated using a cryptographically strong pseudo random number generator.

Returns:
A randomly generated UUID

I was wondering, what algorithms are used for example in Java and .NET for SessionId/AuthenticationToken generation.

Tomcat does not use UUIDs as session tokens but uses a SHA1PRNG secure random generator for producing session IDs:

/**
 * The name of the algorithm to use to create instances of
 * {@link SecureRandom} which are used to generate session IDs. If no
 * algorithm is specified, SHA1PRNG is used. To use the platform default
 * (which may be SHA1PRNG), specify the empty string. If an invalid
 * algorithm and/or provider is specified the {@link SecureRandom} instances
 * will be created using the defaults. If that fails, the {@link
 * SecureRandom} instances will be created using platform defaults.
 */
private String secureRandomAlgorithm = "SHA1PRNG";

This is just the default and you can provide your custom session ID generator by implementing the org.apache.catalina.SessionIdGenerator interface.

Other than using a randomly generated string in the session ID, the standard implementation also adds a jvmRoute to the session IDs that it generates:

A routing identifier for this Tomcat instance. It will be added to the session id to allow for stateless stickyness routing by load balancers. The details on how the jvmRoute will be included in the id are implementation dependent. See Standard Implementation for the default behavior.

Strength of SHA1PRNG has already been discussed here.

Is UUID indeed unsuitable for these purposes in an application that has more than average security needs?

Java UUIDs are almost as secure as Tomcat's default session ID generator which generates 16 byte long session IDs:

Tomcat:

/** Number of bytes in a session ID. Defaults to 16. */
private int sessionIdLength = 16;

java.util.UUID in OpenJDK 7:

public static UUID randomUUID() {
    SecureRandom ng = numberGenerator;
    if (ng == null) {
        numberGenerator = ng = new SecureRandom();
    }

    byte[] randomBytes = new byte[16];
    ng.nextBytes(randomBytes);
    randomBytes[6]  &= 0x0f;  /* clear version        */
    randomBytes[6]  |= 0x40;  /* set to version 4     */
    randomBytes[8]  &= 0x3f;  /* clear variant        */
    randomBytes[8]  |= 0x80;  /* set to IETF variant  */
    return new UUID(randomBytes);
}

But you can configure Tomcat's session ID generator to use more than 16 bytes for added security.

Further reading:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文