首页 文章 精选 留言 我的

精选列表

搜索[文智公众趋势分析],共10000篇文章
优秀的个人博客,低调大师

一文详解安全随机数

本文分享自华为云社区《【安全攻防】深入浅出实战系列专题-安全随机数》,作者: 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来指定。 securerandom.strongAlgorithms的默认配置一般为NativePRNGBlocking:SUN,在这种设定下 getInstanceStrong()与getInstance("NativePRNGBlocking")等效。 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是通过真随机数生成器生成的,所以不可预测。 有同学肯定好奇,真随机数生成器的速度真的有那么慢吗?我们实际验证下,使用真随机数生成器、伪随机数生成器的性能对比如下: 点击关注,第一时间了解华为云新鲜技术~

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册