首页 > 其他分享 >一文详解安全随机数

一文详解安全随机数

时间:2023-12-07 15:33:22浏览次数:39  
标签:一文 生成器 dev 生成 安全 详解 随机数 使用

本文分享自华为云社区《【安全攻防】深入浅出实战系列专题-安全随机数》,作者: 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
及以上版本时,推荐优先使用该方式生成安全随机数。该方式生成随机数是兼顾安全跟效率周期补种真随机数方式的封装,所以在高频生成安全随机数的场景中可以使用该方式。

推荐写法可参考编程规范:

1.png

小结一下:

低频使用安全随机数的业务场景(对性能没有要求)可以使用SecureRandom.getInstance("NativePRNGBlocking")或者SecureRandom.getInstanceStrong()方式;

高频使用安全随机数的业务场景(对性能有要求)只能使用SecureRandom.getInstance("DRBG",...)方式;

上述方式都不能满足业务场景需求时,再考虑自己实现补种、补熵等逻辑(不推荐、一般也不会有)。

实战验证

我们使用SHA1PRNG类型的随机数生成器,验证设置同样的种子seed后,是否能产生同样的随机数序列。

2.png

执行结果如下:可以看到,不管重复执行多少次,只要初始设置的种子相同,后面的序列一定是相同、且固定的。

3.png 4.png

所以如果使用了不安全的随机数生成器实现的代码逻辑,一旦攻击者掌握了一定数量的随机数序列,就有可能推测出初始种子,从而完全预测到后续生成的随机数序列的具体内容。

如果使用真随机数设置种子(当前写法仅为示例,并非推荐写法)

5.png

可以看到,每次执行都有随机性,由于设置的seed是通过真随机数生成器生成的,所以不可预测。

6.png 7.png

有同学肯定好奇,真随机数生成器的速度真的有那么慢吗?我们实际验证下,使用真随机数生成器、伪随机数生成器的性能对比如下:

8.png

点击关注,第一时间了解华为云新鲜技术~

 

标签:一文,生成器,dev,生成,安全,详解,随机数,使用
From: https://www.cnblogs.com/huaweiyun/p/17882134.html

相关文章

  • HydroOJ 从入门到入土(4)控制面板-系统设置详解
    控制面板内众多配置项眼花缭乱,至于说明文档...这个真没有!这里的配置有很多,如果装了插件,有一些插件的配置项也是在这里修改,所以很有必要了解一下这些选项都是干什么的.目录SMTP设置服务器设置setting_limits各种保护性限制基础设置Session设置hydroojui-default显......
  • Java开发者必备:Maven简介及使用方法详解!
    今天我们来介绍一个在Java开发中非常重要的工具——Maven。如果你是一名Java开发者,那么你一定不会对Maven感到陌生。但是,对于一些新手来说,可能还不太了解Maven是什么,它有什么作用,以及如何使用它。接下来,就让我们一起来深入了解一下Maven吧!一、maven简介Maven是什么Maven是一个......
  • 一文详解安全随机数
    本文分享自华为云社区《【安全攻防】深入浅出实战系列专题-安全随机数》,作者:MDKing。随机数的使用场景使用随机数可分类安全场景跟非安全场景。非安全场景需要生成的越快越好。安全场景使用的随机数必须足够安全,保证不能被预测到。常见的非安全场景:数据的索引号、标识;文件的名称或......
  • 神经网络优化篇:详解训练,验证,测试集(Train / Dev / Test sets)
    训练,验证,测试集在配置训练、验证和测试数据集的过程中做出正确决策会在很大程度上帮助大家创建高效的神经网络。训练神经网络时,需要做出很多决策,例如:神经网络分多少层每层含有多少个隐藏单元学习速率是多少各层采用哪些激活函数创建新应用的过程中,不可能从一开始......
  • 【Kubernetes存储篇】StorageClass存储类动态生成PV详解
    一、StorageClass存储类理论StorageClass的作用主要有以下几个方面:动态存储卷分配:StorageClass可以根据定义的属性动态地创建存储卷,无需手动创建和管理存储卷。存储卷的属性管理:StorageClass可以定义存储卷的属性,如存储类型、存储容量、访问模式等,从而更好地满足应用程序的存储需......
  • python 中的 collections 模块:常用数据结构和工具详解
    Python的collections模块提供了许多有用的数据结构,超越了标准的内置数据类型。这些数据结构解决了各种常见的编程问题,包括但不限于高效的容器类型、特定目的的容器、默认值字典等。让我们深入了解其中的几个重要数据结构和工具。1.defaultdict:带有默认值的字典defaultdict是d......
  • 虚拟机安装详解
    虚拟机安装详解 虚拟机安装 1.选择虚拟机软件
在安装虚拟机之前,需要选择一款合适的虚拟机软件。目前市面上有很多虚拟机软件供选择,如VMware、VirtualBox等。根据你的需求和操作系统的支持情况,选择合适的虚拟机软件。2.下载操作系统镜像文件
购买虚拟主机空间后,你会得到......
  • Linux I/O重定向与管道详解
    LinuxI/O重定向与管道详解 原理
在Linux中,I/O重定向是通过重定向符号实现的。标准输入重定向使用符号“<”,标准输出重定向使用符号“>”。
例如,将文件file.txt的内容输出到终端,可以使用以下命令:catfile.txt将文件file.txt的内容输出到文件output.txt,可以使用以下命令:ca......
  • css3 flex弹性布局详解
    一、flexbox弹性盒子2009年,W3C提出了一种新的方案----Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。二、基本概念Flex是 Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。......
  • 线程中断方法详解interrupt
    线程中断方法详解interrupt由于stop中断线程方法过于暴力,就像是突然你正在开发,突然停电一样于是衍生出中断方法interrupt简介线程中断并不会使线程立即退出,而是给线程发送一个通知,告知目标线程,有人希望你退出了!至于目标线程接收到通知之后如何处理,则完全由目标线程自己决定Thread提......