diff --git a/lib/secrets.js b/lib/secrets.js
index 32adfcb6cd7204485224a35978d29aca057a51da..b2ad66e942cb54acdb38ed9caa014e8a44d7e8b7 100644
--- a/lib/secrets.js
+++ b/lib/secrets.js
@@ -37,14 +37,32 @@ const
 path = require('path'),
 fs = require('fs'),
 jwk = require('jwcrypto/jwk'),
-jwt = require('jwcrypto/jwt');
+jwt = require('jwcrypto/jwt'),
+Buffer = require('buffer').Buffer;
+
+
+function randomBytes(length) {
+  var buf = new Buffer(length);
+  var fd = fs.openSync('/dev/urandom', 'r');
+  fs.readSync(fd, buf, 0, buf.length, 0);
+  fs.closeSync(fd);
+  return buf;
+}
+
+exports.randomBytes = randomBytes;
 
 exports.generate = function(chars) {
   var str = "";
   const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+  var bytes = randomBytes(chars);
+
+  // yes, we are biasing the output here a bit.
+  // I'm ok with that. We can improve this over time.
   for (var i=0; i < chars; i++) {
-    str += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
+    str += alphabet.charAt(bytes[i] % alphabet.length);
   }
+  
   return str;
 }