#2681 util::Random Vs sys::Int.random

jhughes Wed 31 Jan 2018

In an attempt to implement a SCRAM login mechanism based on the article here

I found that the SecureRandom is not javascript friendly. I can switch this to sys:Int.random easy enough but i'm not entirely sure why one method is considered to have cryptographic strength and the other not.

Inspecting the source of both of these methods, Random.next and sys::Int.random appear to call the same method however the contents of these methods are empty. Not really sure what the underlying methods are that do the work to generate these random numbers since the direct source inspection shows empty methods(obviously they work) but why one is considered secure and one is not is not clear to me.

SlimerDude Wed 31 Jan 2018

I can't comment on cryptographic strengths, but the JS implementation for sys::Int.random can be found here:

fan.sys.Int.random = function(r)
{
  if (r === undefined) return Math.floor(Math.random() * Math.pow(2, 64));
  else
  {
    var start = r.start();
    var end   = r.end();
    if (r.inclusive()) ++end;
    if (end <= start) throw fan.sys.ArgErr.make("Range end < start: " + r);
    r = end-start;
    if (r < 0) r = -r;
    return Math.floor(Math.random()*r) + start;
  }
}

Seems to make use of Javascript's Math.random() method.

The MDN docs say:

Math.random() does not provide cryptographically secure random numbers. Do not use them for anything related to security. Use the Web Crypto API instead, and more precisely the window.crypto.getRandomValues() method.

So you may need to create your own native Javascript method for a secure random number.

andy Wed 31 Jan 2018

I found that the SecureRandom is not javascript friendly

Use the Web Crypto API instead, and more precisely the window.crypto.getRandomValues() method.

This seems to be well supported, so we should be able to port util::Random to JavaScript. I'll open a ticket.

but i'm not entirely sure why one method is considered to have cryptographic strength and the other not

Typically this just means you can guarantee the "randomness" does not repeat or is in some way predictable -- obviously that is a problem for crypto purposes :)

I'm sure someone out there who knows more that I do can expound.

andy Wed 31 Jan 2018

Ticket promoted to #2681 and assigned to andy

Add @Js support to util::Random

jhughes Wed 31 Jan 2018

In case anybody hits this topic before this ticket is resolved and needs secure random in the browser, this is how I used the provided links to allow for the window.crypto function.

Taking the example exactly as written from here

And putting into a script block during an onGet method of a WebMod

override onGet(){
  res.headers["Content-Type"] = "text/html; charset=utf-8"
  out := res.out
  out.docType
  out.html
  out.head
  out.title.w("RandomTest").titleEnd
  ...
  out.script.w(genRandom).scriptEnd
  ...
  out.headEnd
  out.body
  out.bodyEnd
  out.htmlEnd
}

private Str genRandom(){
  return "var array = new Uint32Array(10);\n" +
  "window.crypto.getRandomValues(array);\n" +
  "console.log(\"Your Lucky Numbers:\");\n" +
  "for(var i=0;i<array.length;i++){\n" +
  "console.log(array[i])}";
}

Login or Signup to reply.