JavaScript 中的安全随机?

发布于 2024-11-05 12:55:14 字数 67 浏览 0 评论 0原文

JavaScript 中是否有类似于 SecureRandom.hex() 的 (ruby) 函数可以为我生成随机哈希?

Is there a SecureRandom.hex()-like (ruby) function in JavaScript which generates a random hash for me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

记忆里有你的影子 2024-11-12 12:55:14

我使用以下关键字将这个问题作为顶级搜索引擎结果:

  • securerandom range js
  • securerandom js

因此,我认为最好用今天(2019)可用的答案更新这篇文章:

下面的代码片段采用 < a href="https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues" rel="nofollow noreferrer">Crypto.getRandomValues() 用于获取据说是的随机值,

...加密性强...使用伪随机数生成器,该生成器以具有足够熵的值作为种子...适合加密用途。

因此,我们有:

var N = 32;
var rng = window.crypto || window.msCrypto;
var rawBytes = Array
              .from(rng.getRandomValues(new Uint8Array(N)))
              .map(c => String.fromCharCode(c))
              .join([]);

现在,下面是一个有趣的小十六进制编码器,我使用一些 Array 函数进行循环,将其作为单行代码编写:

function hexEncode(s) {
  return s.split('').map(c => (c < String.fromCharCode(16) ? '0' : '') + c.charCodeAt(0).toString(16)).join([]);
}

最后,如果您想将上面的两个结合起来以生成随机数哈希值,您只需相应地交换和调整 .map() 函数,然后将其打包,如下所示:

function secureRandomHash(N) {
  N = N || 32; // Coalesce if size parameter N is left undefined

  // TODO: Consider refactoring with lazy-loaded function
  // to set preferred RNG provider, else throw an error here
  // to generate noise that no secure RNG is available for
  // this application.
  var rng = window.crypto || window.msCrypto;

  return Array
           .from(rng.getRandomValues(new Uint8Array(N)))
           .map(c => (c < 16 ? '0' : '') + c.toString(16)).join([]);
}

快乐编码!

编辑:事实证明,我最终在自己的项目中需要这个,该项目还实现了上一个示例中建议的 TODO(延迟加载),所以我们开始:

Math.secureRandom = function() {
  var rng = window.crypto || window.msCrypto;
  if (rng === undefined)
    throw 'No suitable RNG found';

  // Lazy-load this if- branch
  Math.secureRandom = function() {
    // More secure implementation of Math.random (https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#Examples)
    return rng.getRandomValues(new Uint32Array(1))[0] / 4294967296;
  };

  return Math.secureRandom();
}

或者如果您真的很喜欢冒险...... 扩展 Math

// Auto-upgrade Math.random with a more secure implementation only if crypto is available
(function() {
  var rng = window.crypto || window.msCrypto;
  if (rng === undefined)
    return;

  // Source: https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#Examples
  Math.random = function() {
    return rng.getRandomValues(new Uint32Array(1))[0] / 4294967296;
  };
})();

console.log(Math.random());

覆盖 Math.random() 以进行直接替换是否适合您的应用程序或目标受众,这纯粹是留给实现者的学术练习。请务必先咨询您的建筑师!当然要在这里获得麻省理工学院的许可:)

I was led to this question as a top search engine result using the following keywords:

  • securerandom range js
  • securerandom js

As such, I thought it would be good to update this post with a working answer available today (2019):

The snippet below employs Crypto.getRandomValues() for sourcing random values said to be,

... cryptographically strong ... using a pseudo-random number generator seeded with a value with enough entropy ... suitable for cryptographic usages.

Thus, we have:

var N = 32;
var rng = window.crypto || window.msCrypto;
var rawBytes = Array
              .from(rng.getRandomValues(new Uint8Array(N)))
              .map(c => String.fromCharCode(c))
              .join([]);

Now, below is a fun little hex-encoder I cooked up as a one-liner using some Array functions for looping:

function hexEncode(s) {
  return s.split('').map(c => (c < String.fromCharCode(16) ? '0' : '') + c.charCodeAt(0).toString(16)).join([]);
}

Finally, if you want to combine the two above for generating random hashes, you can just swap out and adapt the .map() function accordingly and package it up like so:

function secureRandomHash(N) {
  N = N || 32; // Coalesce if size parameter N is left undefined

  // TODO: Consider refactoring with lazy-loaded function
  // to set preferred RNG provider, else throw an error here
  // to generate noise that no secure RNG is available for
  // this application.
  var rng = window.crypto || window.msCrypto;

  return Array
           .from(rng.getRandomValues(new Uint8Array(N)))
           .map(c => (c < 16 ? '0' : '') + c.toString(16)).join([]);
}

Happy coding!

Edit: Turns out I ended up needing this in my own project which also implements the suggested TODO in the previous example (lazy-loading) so here we go:

Math.secureRandom = function() {
  var rng = window.crypto || window.msCrypto;
  if (rng === undefined)
    throw 'No suitable RNG found';

  // Lazy-load this if- branch
  Math.secureRandom = function() {
    // More secure implementation of Math.random (https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#Examples)
    return rng.getRandomValues(new Uint32Array(1))[0] / 4294967296;
  };

  return Math.secureRandom();
}

Or if you're feeling really adventurous...

// Auto-upgrade Math.random with a more secure implementation only if crypto is available
(function() {
  var rng = window.crypto || window.msCrypto;
  if (rng === undefined)
    return;

  // Source: https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#Examples
  Math.random = function() {
    return rng.getRandomValues(new Uint32Array(1))[0] / 4294967296;
  };
})();

console.log(Math.random());

Whether extending Math or overwriting Math.random() for a drop-in replacement is appropriate for your application or target audience is left purely as an academic exercise to the implementor. Be sure to check with your architect first! License MIT here of course :)

孤独患者 2024-11-12 12:55:14

JS 中没有这样的辅助函数。您可以使用以下方法生成相当随机的哈希值:

function hex(n){
 n = n || 16;
 var result = '';
 while (n--){
  result += Math.floor(Math.random()*16).toString(16).toUpperCase();
 }
 return result;
}

您可以修改它以形成 guid:

function generateGuid(){
 var result = '', n=0;
 while (n<32){
  result += (~[8,12,16,20].indexOf(n++) ? '-': '') +    
            Math.floor(Math.random()*16).toString(16).toUpperCase();
 }
 return result;
}

There is no such helper function in JS. You can generates a fairly random hash using:

function hex(n){
 n = n || 16;
 var result = '';
 while (n--){
  result += Math.floor(Math.random()*16).toString(16).toUpperCase();
 }
 return result;
}

You can modify it to form a guid:

function generateGuid(){
 var result = '', n=0;
 while (n<32){
  result += (~[8,12,16,20].indexOf(n++) ? '-': '') +    
            Math.floor(Math.random()*16).toString(16).toUpperCase();
 }
 return result;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文