SecureRandom使用SHA1PRNG调用reseed抛出UnsupportedOperationException如何解决
问题原因分析
SecureRandom的reseed()是可选实现的API,仅部分随机数算法的底层实现支持该操作:
DRBG是NIST标准化的伪随机数生成器,规范强制要求支持重播种能力,因此OpenJDK/OracleJDK的默认DRBG实现提供了reseed()方法,调用正常。SHA1PRNG是Sun公司早期推出的专有随机数实现,设计之初就没有对外暴露重播种的相关能力,因此调用reseed()会直接抛出UnsupportedOperationException。
解决方案
方案1:优先替换为DRBG算法(推荐)
DRBG是当前Java官方推荐的安全随机数算法,安全性远高于老旧的SHA1PRNG,完全覆盖SHA1PRNG的所有使用场景,天然支持重播种需求:
val rng : SecureRandom = SecureRandom.getInstance("DRBG") rng.reseed()
方案2:必须使用SHA1PRNG时的替代实现
如果因为历史兼容等原因必须保留SHA1PRNG的使用,可以用两种方式替代reseed()的效果:
- 手动调用
setSeed()方法传入新的安全种子,该方法是SHA1PRNG原生支持的,会将新种子和原有内部状态混合,实现等价于重播种的效果:val rng : SecureRandom = SecureRandom.getInstance("SHA1PRNG") // 传入32位安全随机种子完成重播种,种子长度可根据业务需求调整 rng.setSeed(SecureRandom.getSeed(32)) - 不需要保留原有实例时,直接重新实例化SHA1PRNG,新实例会自动调用系统熵源完成初始播种,也等价于重播种:
var rng : SecureRandom = SecureRandom.getInstance("SHA1PRNG") // 需要重播种时替换为新实例 rng = SecureRandom.getInstance("SHA1PRNG")
注意事项
SHA1PRNG属于已过时的实现,不同JDK厂商的实现逻辑差异极大,部分高版本JDK已经将其标记为废弃,非必要场景不建议继续使用。
内容的提问来源于stack exchange,提问作者cershif
相关产品推荐
相关产品推荐

