根据NIST特别出版物800-90A修订版1,使用确定性随机比特生成器生成随机数的推荐(800-90Ar1),
DRBG基于本推荐中指定的DRBG机制,并包括一个随机性源。 DRBG机制使用一个算法(即DRBG算法),该算法从由随机性源的输出确定的种子确定的初始值中产生一系列比特。
800-90Ar1规范允许各种DRBG实现选择,例如:
- 熵源,
- DRBG机制(例如,Hash_DRBG),
- DRBG算法(例如,Hash_DRBG的SHA-256和CTR_DRBG的AES-256。请注意,这不是在
SecureRandom.getInstance(java.lang.String)
中使用的算法,我们将其称为SecureRandom算法), - 可选功能,包括预测抵抗和重新播种支持,
- 最高安全强度。
这些选择在每个实现中设置,不是由SecureRandom
API 直接管理。查看您的DRBG提供程序的文档,以找到适合情况的实现。
另一方面,800-90Ar1规范确实具有一些可配置选项,例如:
- 所需的安全强度,
- 是否需要预测抵抗,
- 个性化字符串和附加输入。
DRBG实例可以使用来自DrbgParameters.Instantiation
对象和其他信息(例如,nonce,不由此API管理)的参数实例化。这映射到NIST SP 800-90Ar1中定义的Instantiate_function
。
DRBG实例可以使用来自DrbgParameters.Reseed
对象的参数重新播种。这映射到NIST SP 800-90Ar1中定义的Reseed_function
。调用SecureRandom.reseed()
等效于使用有效实例化的预测抵抗标志(由SecureRandom.getParameters()
返回)调用SecureRandom.reseed(SecureRandomParameters)
,没有附加输入。
DRBG实例使用来自DrbgParameters.NextBytes
对象的附加参数生成数据。这映射到NIST SP 800-90Ar1中定义的Generate_function
。调用SecureRandom.nextBytes(byte[])
等效于使用由SecureRandom.getParameters()
返回的有效实例化强度和预测抵抗标志(没有附加输入)调用SecureRandom.nextBytes(byte[], SecureRandomParameters)
。
DRBG应该作为SecureRandomSpi
的子类实现。建议实现包含接受DrbgParameters.Instantiation
参数的1个参数的构造函数。如果以这种方式实现,则可以通过任何SecureRandom.getInstance()
方法选择该实现。如果通过具有SecureRandomParameters
参数的SecureRandom.getInstance()
选择它,则将该参数传递到此构造函数。如果通过没有SecureRandomParameters
参数的SecureRandom.getInstance()
选择它,则使用null
参数调用构造函数,并且实现应选择自己的参数。其SecureRandom.getParameters()
必须始终返回一个反映DRBG实际实例化方式的非空有效DrbgParameters.Instantiation
对象。调用者可以使用此信息确定SecureRandom
对象是否为DRBG以及它支持的功能。请注意,返回的值不一定等于传递给SecureRandom.getInstance()
调用的DrbgParameters.Instantiation
对象。例如,请求的功能可以是DrbgParameters.Capability.NONE
,但如果实现支持重新播种,则有效值可以是DrbgParameters.Capability.RESEED_ONLY
。实现必须实现接受DrbgParameters.NextBytes
参数的SecureRandomSpi.engineNextBytes(byte[], SecureRandomParameters)
方法。除非SecureRandom.getParameters()
的结果具有其功能为NONE
,否则必须实现SecureRandomSpi.engineReseed(SecureRandomParameters)
,该方法接受DrbgParameters.Reseed
参数。
另一方面,如果DRBG实现不包含具有DrbgParameters.Instantiation
参数的构造函数(不推荐),则只能通过不带SecureRandomParameters
参数的SecureRandom.getInstance()
选择它,但如果调用具有SecureRandomParameters
参数的getInstance
方法,则不会选择它。如果以这种方式实现,则其SecureRandom.getParameters()
必须返回null
,并且不需要实现SecureRandomSpi.engineNextBytes(byte[], SecureRandomParameters)
或SecureRandomSpi.engineReseed(SecureRandomParameters)
。
如果种子周期大于DRBG机制定义的最大种子生命周期,则DRBG可能会自动重新播种。
DRBG实现应支持通过保留配置和有效参数进行序列化和反序列化,但不必序列化内部状态,并且反序列化的对象必须重新实例化。
示例:
SecureRandom drbg; byte[] buffer = new byte[32]; // 任何DRBG都可以 drbg = SecureRandom.getInstance("DRBG"); drbg.nextBytes(buffer); SecureRandomParameters params = drbg.getParameters(); if (params instanceof DrbgParameters.Instantiation) { DrbgParameters.Instantiation ins = (DrbgParameters.Instantiation) params; if (ins.getCapability().supportsReseeding()) { drbg.reseed(); } } // 以下调用请求一个弱DRBG实例。仅保证支持112位的安全强度。 drbg = SecureRandom.getInstance("DRBG", DrbgParameters.instantiation(112, NONE, null)); // 下面两个调用可能会失败,因为drbg可能是用较小的强度实例化的,没有预测抵抗支持。 drbg.nextBytes(buffer, DrbgParameters.nextBytes(256, false, "more".getBytes())); drbg.nextBytes(buffer, DrbgParameters.nextBytes(112, true, "more".getBytes())); // 以下调用请求一个强DRBG实例,带有个性化字符串。如果成功返回一个实例,则保证该实例支持256位的安全强度,并提供预测抵抗。 drbg = SecureRandom.getInstance("DRBG", DrbgParameters.instantiation( 256, PR_AND_RESEED, "hello".getBytes())); // 此单个调用未请求预测抵抗,但使用了附加输入。 drbg.nextBytes(buffer, DrbgParameters.nextBytes(-1, false, "more".getBytes())); // 对于此调用也是如此。 drbg.reseed(DrbgParameters.reseed(false, "extra".getBytes()));
- 实现要求:
-
按照惯例,提供程序应使用标准
SecureRandom
算法名称“DRBG”命名其主要DRBG实现。 - 实现说明:
-
以下说明适用于JDK参考实现的SUN提供程序中的“DRBG”实现。
此实现支持使用DRBG算法SHA-224、SHA-512/224、SHA-256、SHA-512/256、SHA-384和SHA-512的Hash_DRBG和HMAC_DRBG机制,以及使用AES-128、AES-192和AES-256的DRBG算法的CTR_DRBG(使用派生函数和不使用派生函数)。
机制名称和DRBG算法名称由
securerandom.drbg.config
安全属性确定。默认选择是使用SHA-256的Hash_DRBG。对于每种组合,可以请求从112到其支持的最高强度的安全强度。同时支持重新播种和预测抵抗。
通过
DrbgParameters.Instantiation
类支持个性化字符串,通过DrbgParameters.NextBytes
和DrbgParameters.Reseed
类支持附加输入。如果DRBG未显式使用
DrbgParameters.Instantiation
对象实例化,则此实现将使用默认请求的强度为128位,不请求预测抵抗,也不请求个性化字符串进行实例化。这些默认实例化参数也可以通过securerandom.drbg.config
安全属性进行自定义。此实现从由安全属性
securerandom.source
确定的系统默认熵源中读取新鲜熵。调用
SecureRandom.generateSeed(int)
将直接从此系统默认熵源中读取。 - 自:
- 9
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic enum
DRBG的可重新播种和预测抵抗能力。static final class
用于实例化的DRBG参数。static final class
用于生成随机比特的DRBG参数。static final class
重新种子的DRBG参数。 -
Method Summary
Modifier and TypeMethodDescriptionstatic DrbgParameters.Instantiation
instantiation
(int strength, DrbgParameters.Capability capability, byte[] personalizationString) 生成一个DrbgParameters.Instantiation
对象。static DrbgParameters.NextBytes
nextBytes
(int strength, boolean predictionResistance, byte[] additionalInput) 生成一个DrbgParameters.NextBytes
对象。static DrbgParameters.Reseed
reseed
(boolean predictionResistance, byte[] additionalInput) 生成一个DrbgParameters.Reseed
对象。
-
Method Details
-
instantiation
public static DrbgParameters.Instantiation instantiation(int strength, DrbgParameters.Capability capability, byte[] personalizationString) 生成一个DrbgParameters.Instantiation
对象。- 参数:
-
strength
- 以位为单位的安全强度,如果在getInstance
中使用,则为-1表示默认强度。 -
capability
- 能力 -
personalizationString
- 个性化字符串作为字节数组,可以为null
。此字节数组的内容将被复制。 - 返回:
-
一个新的
Instantiation
对象 - 抛出:
-
NullPointerException
- 如果capability
为null
-
IllegalArgumentException
- 如果strength
小于-1
-
nextBytes
public static DrbgParameters.NextBytes nextBytes(int strength, boolean predictionResistance, byte[] additionalInput) 生成一个DrbgParameters.NextBytes
对象。- 参数:
-
strength
- 请求的安全强度,以位为单位。如果设置为-1,则将使用有效强度。 -
predictionResistance
- 请求的预测抵抗 -
additionalInput
- 附加输入,可以为null
。此字节数组的内容将被复制。 - 返回:
-
一个新的
NextBytes
对象 - 抛出:
-
IllegalArgumentException
- 如果strength
小于-1
-
reseed
生成一个DrbgParameters.Reseed
对象。- 参数:
-
predictionResistance
- 请求的预测抵抗 -
additionalInput
- 附加输入,可以为null
。此字节数组的内容将被复制。 - 返回:
-
一个新的
Reseed
对象
-