javascript七基础学习系列一千八百九十:Web Cryptography API

Web Cryptography API 描述了一套密码学工具,规范了JavaScript 如何以安全和符合惯例的方式实现
加密。这些工具包括生成、使用和应用加密密钥对,加密和解密消息,以及可靠地生成随机数。
生成随机数
在需要生成随机值时,很多人会使用Math.random()。这个方法在浏览器中是以伪随机数生成器
(PRNG,PseudoRandom Number Generator)方式实现的。所谓“伪”指的是生成值的过程不是真的随机。
PRNG 生成的值只是模拟了随机的特性。浏览器的PRNG 并未使用真正的随机源,只是对一个内部状态
应用了固定的算法。每次调用Math.random(),这个内部状态都会被一个算法修改,而结果会被转换
为一个新的随机值。例如,V8 引擎使用了一个名为xorshift128+的算法来执行这种修改。
由于算法本身是固定的,其输入只是之前的状态,因此随机数顺序也是确定的。xorshift128+使用
128 位内部状态,而算法的设计让任何初始状态在重复自身之前都会产生2128–1 个伪随机值。这种循环
被称为置换循环(permutation cycle),而这个循环的长度被称为一个周期(period)。很明显,如果攻击
者知道PRNG 的内部状态,就可以预测后续生成的伪随机值。如果开发者无意中使用PRNG 生成了私有
密钥用于加密,则攻击者就可以利用PRNG 的这个特性算出私有密钥。
伪随机数生成器主要用于快速计算出看起来随机的值。不过并不适合用于加密计算。为解决这个问
题,密码学安全伪随机数生成器(CSPRNG,Cryptographically Secure PseudoRandom Number Generator)
额外增加了一个熵作为输入,例如测试硬件时间或其他无法预计行为的系统特性。这样一来,计算速度
明显比常规PRNG 慢很多,但CSPRNG 生成的值就很难预测,可以用于加密了。
Web Cryptography API 引入了CSPRNG,这个CSPRNG 可以通过crypto.getRandomValues()在全
局Crypto 对象上访问。与Math.random()返回一个介于0 和1 之间的浮点数不同,getRandomValues()
会把随机值写入作为参数传给它的定型数组。定型数组的类不重要,因为底层缓冲区会被随机的二进制
位填充。
下面的例子展示了生成5 个8 位随机值:
const array = new Uint8Array(1);
for (let i=0; i<5; ++i) {
console.log(crypto.getRandomValues(array));
}
// Uint8Array [41]
// Uint8Array [250]
// Uint8Array [51]
// Uint8Array [129]
// Uint8Array [35]
getRandomValues()最多可以生成216(65 536)字节,超出则会抛出错误:
const fooArray = new Uint8Array(2 ** 16);
console.log(window.crypto.getRandomValues(fooArray)); // Uint32Array(16384) […]
const barArray = new Uint8Array((2 ** 16) + 1);
console.log(window.crypto.getRandomValues(barArray)); // Error
要使用CSPRNG 重新实现Math.random(),可以通过生成一个随机的32 位数值,然后用它去除
最大的可能值0xFFFFFFFF。这样就会得到一个介于0 和1 之间的值:
function randomFloat() {
// 生成32 位随机值
const fooArray = new Uint32Array(1);
// 最大值是2^32 –1
const maxUint32 = 0xFFFFFFFF;
// 用最大可能的值来除
return crypto.getRandomValues(fooArray)[0] / maxUint32;
}
console.log(randomFloat()); // 0.5033651619458955

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值