一文详解安全随机数
本文分享自华为云社区《【安全攻防】深入浅出实战系列专题-安全随机数》,作者: MDKing 。
随机数的使用场景
使用随机数可分类安全场景跟非安全场景。非安全场景需要生成的越快越好。安全场景使用的随机数必须足够安全,保证不能被预测到。
常见的非安全场景:
-
数据的索引号、标识;
-
文件的名称或目录;
-
UUID、用户ID、随机填充字节;
常见安全场景包括但不限于以下场景:
-
用于密码算法用途,如生成IV、盐值、密钥等;
-
会话标识(sessionId)的生成;
-
挑战算法中的随机数生成;
-
验证码的随机数生成;
密码学意义上的安全随机数
安全场景下使用的随机数必须是密码学意义上的安全随机数。
密码学意义上的安全随机数分为两类:
-
真随机数产生器产生的随机数;
-
以真随机数产生器产生的少量随机数作为种子的密码学安全的伪随机数产生器产生的大量随机数。
已知的可供产品使用的密码学安全的非物理真随机数产生器有:
-
Linux操作系统的/dev/random设备接口(存在阻塞问题)
-
Windows操作系统的 CryptGenRandom() 接口
我们可以看到,密码学意义上的安全随机数非指必须都为真随机数生成器生成,因为真随机数生成器产生随机数是需要资源(熵)消耗的,当资源不足时会阻塞。所以在业务使用随机数频次较低的时候可以考虑全部使用真随机数。在业务使用随机数的频次高、数量大时就必须使用兼顾安全跟效率的方式:使用伪随机数生成器作为主体生成器进行随机数生成,使用真随机数周期为其设置种子(seed)。
SecureRandom对象的生成随机数有两类方法:生成下一个随机数的方法,比如nextInt、nextBytes等;生成种子的方法,如generateSeed。
使用new SecureRandom()创建的对象的nextXXX、generateSeed方法在linux系统下随机数来源均为/dev/urandom,生成的随机数都是不安全随机数。
使用SecureRandom.getInstance("SHA1PRNG", "SUN")创建的对象nextXXX生成的为不安全的随机数,generateSeed生成的为安全随机数(linux下来源为/dev/random),所以使用SHA1PRNG算法合理设置好周期补种的逻辑理论上是可行的。但是根据公司密码算法相关要求,从2023年开始将禁止使用SHA1PRNG算法生成安全随机数。
常用推荐的安全随机数用法
大的原则上不建议自己实现补种、刷新熵源等逻辑,最好直接使用JDK封装好的方法。
密码学安全的随机数用法主要有3种:
1. SecureRandom.getInstance("NativePRNGBlocking")
参数要配置NativePRNGBlocking,好处是非常安全,因为nextXXX、generateSeed方法都是生成的真随机数,缺点是因为每次都是真随机数,性能较低,会有阻塞性问题。常见几个参数的对比如下:
参数取值 | 说明 | nextXXX的随机数源 | generateSeed的随机数源 | 随机数质量 | 是否阻塞(没实际验证,读者自酌) |
---|---|---|---|---|---|
SHA1PRNG | 通过系统属性和java.security的熵收集设备完成随机数生成器的初始播种。完成初始播种后,不再依赖熵收集设备 | NA | NA | 不安全 | 不阻塞 |
NativePRNG | 完成初始播种后,仍然要从系统的熵收集设备获取随机数,这就是Native的含义。nextBytes()从/dev/urandom设备获取随机数, generateSeed()从/dev/random获取随机数。 | /dev/urandom | /dev/random | 较安全 | 取随机数不阻塞,取种可能阻塞 |
NativePRNGBlocking | nextBytes()和generateSeed()均从/dev/random获取随机数 | /dev/random | /dev/random | 最安全 | 很可能阻塞 |
NativePRNGNonBlocking | nextBytes()和generateSeed()均从/dev/urandom获取随机数 | /dev/urandom | /dev/urandom | 不安全 | 不阻塞 |
2. SecureRandom.getInstanceStrong()
在JDK 8中引入,主要解决getInstance在应用某些参数时不能保证取到的随机数质量足够安全的问题,简化编程。它返回每个平台上可用的最强SecureRandom实现的实例。它会调用系统上可用的最强算法,该算法由$JAVA_HOME/jre/lib/security/java.security中的securerandom.strongAlgorithms来指定。
3. SecureRandom.getInstance("DRBG",...)
从JDK 9开始,新增了由Sun提供的符合NIST SP 800 90-A标准的DRBG伪随机数产生器,包括HASH-DRBG、HMAC-DRBG、CTR-DRBG三种,且适用于各种OS,符合公司密码算法相关要求,在使用JDK 9
及以上版本时,推荐优先使用该方式生成安全随机数。该方式生成随机数是兼顾安全跟效率周期补种真随机数方式的封装,所以在高频生成安全随机数的场景中可以使用该方式。
推荐写法可参考编程规范:
小结一下:
低频使用安全随机数的业务场景(对性能没有要求)可以使用SecureRandom.getInstance("NativePRNGBlocking")或者SecureRandom.getInstanceStrong()方式;
高频使用安全随机数的业务场景(对性能有要求)只能使用SecureRandom.getInstance("DRBG",...)方式;
上述方式都不能满足业务场景需求时,再考虑自己实现补种、补熵等逻辑(不推荐、一般也不会有)。
实战验证
我们使用SHA1PRNG类型的随机数生成器,验证设置同样的种子seed后,是否能产生同样的随机数序列。
执行结果如下:可以看到,不管重复执行多少次,只要初始设置的种子相同,后面的序列一定是相同、且固定的。
所以如果使用了不安全的随机数生成器实现的代码逻辑,一旦攻击者掌握了一定数量的随机数序列,就有可能推测出初始种子,从而完全预测到后续生成的随机数序列的具体内容。
如果使用真随机数设置种子(当前写法仅为示例,并非推荐写法)
可以看到,每次执行都有随机性,由于设置的seed是通过真随机数生成器生成的,所以不可预测。
有同学肯定好奇,真随机数生成器的速度真的有那么慢吗?我们实际验证下,使用真随机数生成器、伪随机数生成器的性能对比如下:

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
全方位解读SeaTunnel MySQL CDC连接器:实现数据高效同步的强大工具
在当今数据快速增长的时代,实时、高效地同步和处理来自各种数据源的信息成为了企业和开发者面临的重要挑战。 MySQL作为广泛使用的数据库之一,其变更数据捕获(CDC)功能对于实现这一目标至关重要。在这篇文章中,我们将深入探讨MySQL CDC源连接器在SeaTunnel框架下的应用,涵盖从基础设置到高级配置的各个方面。 MySQL CDC源连接器 支持的引擎 SeaTunnel Zeta<br/> Flink <br/> 主要特性 [ ] 批量 [x] 流式 [x] 精确一次 [ ] 列投影 [x] 并行处理 [x] 支持用户定义的拆分 描述 MySQL CDC连接器允许从MySQL数据库读取快照数据和增量数据。本文档描述了如何设置MySQL CDC连接器以对MySQL数据库运行SQL查询。 支持的数据源信息 数据源 支持的版本 驱动 Url Maven MySQL <li> MySQL: 5.6, 5.7, 8.0.x </li><li> RDS MySQL: 5.6, 5.7, 8.0.x </li> com.m...
- 下一篇
去哪儿如何实现故障率降低 65%?技术 + 管理的数字化度量体系实践
一分钟精华速览 如何全面把握系统现状,以便在关键时刻做出明智的决策?这是很多负责全局稳定性的管理者深感关切的问题。基于这一背景,同时也为了寻求提升研发工作效率提升,去哪儿网构建了一套数字化质量度量体系,以此来更精确地度量、管理并提升系统稳定性。 本文将详细解读这套质量度量体系,阐述如何在 100 多个指标中筛选出关键的度量标准,并进行有效的优化。同时,也将探讨如何借助这个指标模型理论,衡量系统复杂度并进行系统防腐化治理。这套数字化度量体系让去哪儿网的管理决策更有依据,改进方向更明确,结果也更可控,实现了系统运行状态的可视化。 作者介绍 去哪儿网基础研发产品总监——陈靖贤 TakinTalks 稳定性社区专家团成员,去哪儿网基础研发产品总监。2013 年加入去哪儿网,曾任职于摩托罗拉、索尼移动通信。多年来深耕于 DevOps、研发效能领域,致力于公司内部 DevOps 实践的落地实施,研发与交付流程的优化,工程效率平台工具的建设与推广,覆盖开发、测试、交付、运维研发生命周期全流程。 全面系统提升研发效能,助力业务发展。 温馨提醒:本文约 7000 字,预计花费 10 分钟阅读。 「Tak...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2全家桶,快速入门学习开发网站教程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- 2048小游戏-低调大师作品
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,CentOS7官方镜像安装Oracle11G