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

old*_*bam 21 authentication uuid sessionid

我见过有人使用UUID进行身份验证令牌生成.但是,在RFC 4122中说明了这一点

不要以为UUID难以猜测; 例如,它们不应被用作安全功能(仅仅拥有访问权限的标识符).

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

Sea*_*ean 8

UUID生成是随机的,但随机的熵不好意味着你最终会很容易猜到UUID.如果使用良好的随机数生成器,则可以生成UUID可用于会话的s.然而,对此的关注是,UUIDs没有内置的重新播放防止,篡改,固定等,你必须自己处理(阅读:UUID本身不应被视为一个有效的会话ID本身).也就是说,这是一个很好的代码片段,说明如何UUID使用python以下方法生成安全:

python中的唯一会话ID


Lam*_*bda 7

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


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

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

public static 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";
Run Code Online (Sandbox Code Playgroud)

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

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

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

强度这里SHA1PRNG已经讨论过了。

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

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

雄猫

/** Number of bytes in a session ID. Defaults to 16. */
private int sessionIdLength = 16;
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

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

进一步阅读: