会话Id/身份验证令牌生成的最佳实践

34

我见过有人使用UUID生成认证令牌。然而,在RFC 4122中,它指出:

  

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

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

2个回答

16

UUID生成是随机的,但是当熵值不足时,随机生成的UUID容易被猜测。如果使用良好的随机数生成器,则可以生成可用于会话的UUID。然而,UUID没有内置的重放预防、篡改、固定等功能,您需要自行处理这些问题(即:单独使用UUID本身不应被视为有效的会话ID)。下面是一个使用python生成安全UUID的好代码片段:

在Python中生成唯一的会话ID


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";

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

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

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

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 字节的内容增加安全性。

进一步阅读:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接