不要只是随机化,而是真正地随机化!

编程入门 行业动态 更新时间:2024-10-08 18:34:02

不要只是<a href=https://www.elefans.com/category/jswz/34/1735166.html style=随机化,而是真正地随机化!"/>

不要只是随机化,而是真正地随机化!

Web应用程序加密的状态已更改,每种开发语言都提供了自己的使用方式。 我将介绍随机数生成的当前状态以及在Java和JavaScript开发语言中发现随机数的区别。

在设计和构建Web应用程序时,安全问题显然起着至关重要的作用。 安全一词涵盖了很多领域,包括但不限于:

  • 输入验证
  • 认证方式
  • 会话管理
  • 参数操纵保护
  • 密码学

在之前的DOD /政府项目中,我很幸运地致力于Java安全组件,该组件直接处理最后提到的安全领域:密码学。 具体而言,随机数生成。 来自纯商业Java开发背景,起初,我不得不退后一步,退出技术设计文档,并弄清楚我们如何希望此Web应用程序实施机密性和完整性。

更具体地说,应用程序应如何保密? 我们应该如何为加密强度高的随机值提供种子? 我们应该允许浏览器处理随机数生成还是将其保留在后端? 最后,创建用于加密的随机密钥的最佳方法是什么?

加密和随机性

在安全的Web应用程序开发中,最后一个问题在使用随机性的安全性收益中起着重要作用。 有人可能会说:“嘿,关于加密,仅使用Base64或UTF8编码会怎样?” 说穿了……那是老派! 如今,大多数安全分析人员甚至不再考虑这两种可靠的安全加密方法。

使用随机性的其他示例可能是登录后生成随机质询,创建会话ID或将密钥用于各种加密目的。 关于最后一个示例,为了生成这样的秘密密钥,需要熵池。 不可预测的熵池。 这可以通过验证密码强随机数生成器(CSPRNG)的不可重复输出来实现。

我从与我合作的各个政府安全分析师那里学到的一条经验法则是避免第三方提供的随机数。

有人可能会问:“嗯, http://random怎么了?” 没什么……成为“真正的”随机数生成器确实做得很好。 特别是因为它声称会通过大气噪​​声产生随机性。 但是,如果在这种大气噪声中确实可以检测到模式,那么这种揭穿就是其真正的随机性主张。 从理论上讲,找到物理随机性来源的无偏度量有点困难。 但是我离题了!

有人不能仅通过HTTPS上的SSL来使用Random吗? 是的,但是如果您要在加密安全系统中实施此操作,则不是一个好主意。 甚至。 再有,将您的随机数生成外包会破坏安全系统的目的。

Java

让我们看一下Java语言必须提供的功能。 从Java服务器端的角度来看,Java语言是传统Random类的标准配置。 这对于您可能希望随机化的常规非安全应用程序(例如投币游戏或互动式洗牌机)很好用。 给定其种子=(种子*乘数+ 0xbL)&((1L << 48)– 1),此类的周期很短(2 ^ 48)。 这只会生成一个很小的值组合。

要退后一步, 种子可以帮助您通过初始算法回忆起所生成的相同随机数序列

至少对于1.4之前的Java版本,另一个限制是,当使用默认的Random构造函数生成随机数时,它默认为1970年1月1日以来的当前系统时间(以毫秒为单位)。 因此,如果外部用户碰巧知道应用程序的运行时间,则可以轻松地找出所生成的随机数。

SecureRandom进行救援! 另一方面,SecureRandom会生成加密强度高的随机数。 CSPRNGS使用真正的随机源:熵。

例如,用户的鼠标单击,鼠标移动,键盘输入,特定的计时事件或任何其他与OS相关的随机数据。 因此,它接近成为TRUE随机数生成器。 我说接近是因为至少它们不是由确定性算法生成的。

但是,从理论上讲,再有一次真的是随机的吗? 好吧,没关系这个问题。 请记住,SecureRandom使用来自Java密码服务提供程序一部分的其他类的PRNG实现。 例如,在Windows中,默认情况下,SUN CSP使用SHA1PRNG。 这是可靠的,因为利用此默认的SecureRandom()构造函数,用户可以检索128位种子。 因此,基于其种子源,重复的机会大大少于原始的Java Random类。

自播SecureRandom生成器的简单直接实现:

// Very nice...
// Instantiate secure random generator using the SHA1PRNG algorithm
SecureRandom randomizer = SecureRandom.getInstance(“SHA1PRNG”);// Provide a call to the nextBytes method.  This will force the SecureRandom object to seed itself.
byte[] randomBytes = new byte[128];
randomizer.nextBytes(randomBytes);

另一方面……著名的“保证随机”标准方法:

// No bueno
public int getRandomNumber() {return 7;  // shhhh no one will know... teehee
}

底线:要考虑的最重要的事情是……。 种子! 如果知道种子,则所有伪随机数生成器都是确定性的。 因此,与Random相比,SecureRandom更适合用于强熵源,这一事实使它在低温地形学环境中具有优势。 不利的一面是,所需的熵越大,性能越差。 需要考虑的事情。

JavaScript

那么JavaScript呢? 客户端是否足够值得信赖以处理密码? 总体而言,JavaScript语言的真正安全性如何? 现在,JavaScript和单页应用程序变得越来越流行,这些都是有效而重要的问题。

客户端最常见的不安全因素之一就是HTML注入,由此应用程序可能会在不知不觉中允许第三方将JavaScript注入其安全上下文中。 如今,网站和许多Web应用程序都需要某种客户端加密。 特别是由于浏览器仍然是与远程服务器进行交互时的首选工具。 对于我们JavaScripter来说,幸运的是,最新的浏览器随附了复杂的措施来应对这些不安全因素。

当收集熵时,很明显JavaScript可以很容易地收集键盘输入,鼠标单击等。 然而,难以通过浏览器提供用于确定强随机数的熵,而不会遇到可用性缺陷,例如不得不要求一些用户交互以协助播种伪随机数。

无论如何,这并不重要,因为JavaScript仅带有不带参数的Math.random()函数。 该Math.random()函数会自动植入,类似于Java的Random类,但是可以手动植入该种子吗? 真的没什么。 JavaScript不具备手动植入Math.random()的功能。 有一些插件,其中之一是基于RC-4的流行插件, 可在GitHub上找到 。 它甚至支持Node.js和Require.js。

请记住,所有浏览器都打包有不同的随机数生成器。 Chrome使用“随身携带乘数”生成器。 Firefox和IE使用线性同余生成器(Java Random类也使用线性同余公式进行了修改),因此单独使用Math.random()作为唯一的熵来源并不明智。 面对现实,此功能在密码上并不强大。

一些JavaScript加密库确实提供了一些帮助-CryptoJS是其中之一 。 CryptoJS包含许多用JavaScript编写的安全密码算法。 但是,让我们跳过第三方库,看看Javascript提供了什么。

最近MDN并没有让您失望。 他们正在密码学领域取得长足进步。 例如,window.crypto.getRandomValues()函数的效果很好。 熵收集函数所需要的只是传递一个基于整数的TypeArray,该函数将使用密码随机数填充该数组。 请记住,这是一个实验性的API,这意味着它仍处于“工作草案”状态,但似乎只能在使用强(伪)随机数生成器的一些最新浏览器中使用。 这是一个很棒的链接 ,显示了浏览器与此特定功能的兼容性。

结论

直到代码注入,边信道攻击和跨站点脚本之类的不安全因素不再成为威胁之前,很难将JavaScript视为严重的加密环境。 稍等! 我不建议依靠完全内置的浏览器内加密技术。 如果客户端要处理大多数应用程序安全功能,则可能会打开一大堆蠕虫。

但是,这并不意味着将来不会改变。 也许有一天,将在HTML / JavaScript中内置完整的加密堆栈。 另外,鉴于SPA和Angular等工具的普及,我有一种感觉,window.crypto.getRandomValues()也将有一天被将来的所有浏览器支持。

在那之前,没有什么比在后端生成随机数更好的了。 但是,我的立场是乐观的,我一直在密切注意将来的SPA安全Web开发的内容!

翻译自: .html

更多推荐

不要只是随机化,而是真正地随机化!

本文发布于:2024-03-13 23:55:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1735165.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:随机化

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!