SimpleDRBG는 기본적으로 HMAC 값의 체인을 사용하는 NIST HMAC_Generate 함수 인 단순한 (FIPS와 호환되지 않는) DRBG를 정의합니다. 1 바이트 요청 후 다른 요청은 동시에 2 바이트를 요구하는 것과 같지 않습니다.
하는 randomInt 클래스는 클래스 또는 Node.js.의 crypto
모듈로부터 어느 randomBytes
를 사용할 수있는 클래스 임의의 바운드 된 숫자 또는 범위의 숫자를 만듭니다.
boundedRandomNumber
함수는 먼저 요청 바이트 수를 계산합니다.이 바이트는 필요한 바이트 수보다 조금 더 높습니다. 이 바이트는 candidate
이라는 큰 정수로 변환됩니다. 그런 다음이 값이 반환되고 계수가 계산됩니다.
while 루프는 최저 candidate
값이 0과 X 사이의 값을 반환 할 수 있으므로 스펙트럼 하단의 왜곡이 없는지 확인합니다. bound
을 수행 한 후 X <이 바인딩됩니다. 이 경우 더 많은 바이트가 요청됩니다. 현재 구현에서는 루프가 두 번 이상 수행 될 가능성이 높지 않으므로 이러한 함수는 상대적으로 효율적이어야합니다.
그래서 simpledrbg.js
포함해야 파일 :
crypto = require('crypto');
exports.SimpleDRBG = function (k) {
this.k = k;
this.v = new Buffer(0);
}
exports.SimpleDRBG.prototype.randomBytes = function(bytes) {
var result = new Buffer(0);
var generatedBytes = 0;
while (generatedBytes < bytes) {
this.hmac = crypto.createHmac('sha512', this.k);
this.hmac.update(this.v);
this.v = this.hmac.digest();
var tocopy = Math.min(this.v.length, bytes - generatedBytes);
if (tocopy == this.v.length) {
result = Buffer.concat([result, this.v]);
} else {
var vslice = this.v.slice(0, tocopy);
result = Buffer.concat([result, vslice]);
}
generatedBytes += tocopy;
}
return result;
}
및 randomint.js
이 포함되어 있어야합니다
crypto = require('crypto'),
bigint = require('bigint');
drbg = require('./simpledrbg');
function RandomInt(randomizer) {
this.randomizer = randomizer;
}
/**
* Returns a bounded random number, i.e. in the range [0..bound).
* The highest possible value that may be returned is bound - 1.
* Use boundedRandomNumber (bound + 1) if you want the bound value to
* be the highest possible value that can be returned.
*/
RandomInt.prototype.boundedRandomNumber = function (bound) {
BYTE_SIZE = 8;
bigBound = bigint(bound);
bigBoundLen = bigint(bigBound.bitLength());
// request a higher number of bytes just to be sure that
// the candidates are selected with high probability
bytesToRequest = bigBoundLen.add(BYTE_SIZE).sub(1).div(BYTE_SIZE).add(1);
// bigBound won't fit an integral number of times in the max value returned
// so if it is higher than the largest n times bigBound, we need to try
// again
maxCandidateExcl = bigint(0x100).pow(bytesToRequest).div(bigBound).mul(bigBound);
// just an assignment that will skip the initial test
candidate = maxCandidateExcl;
while (candidate.ge(maxCandidateExcl)) {
bytes = this.randomizer.randomBytes(bytesToRequest.toNumber());
candidate = bigint.fromBuffer(bytes);
}
// return the well distributed candidate % bound
return candidate.mod(bigBound).toNumber();
}
/**
* Returns a ranged random number, i.e. in the range [lowerBound..upperBound).
* The highest possible value that may be returned is upperBound - 1.
* Use rangedRandomNumber (lowerBound, upperBound + 1) if you want the upperBound value to
* be the highest possible value that can be returned.
*/
RandomInt.prototype.rangedRandomNumber = function (lowerBound, upperBound) {
return lowerBound + boundedRandomNumber (upperBound - lowerBound);
}
var randomIntTRNG = new RandomInt(crypto);
var testTRNG = randomIntTRNG.boundedRandomNumber(1000000);
console.log(testTRNG);
var randomIntDRNG = new RandomInt(new drbg.SimpleDRBG('seed'));
var testDRNG = randomIntDRNG.boundedRandomNumber(1000000);
console.log(testDRNG);
왜 createHmac()를 사용하고 있습니까? 더 나은 도구가 있고, 이것은 createHmac()가 필요한 것이 아닙니다. try crypto.randomBytes() – dandavis
다른 도구를 가르쳐 주시겠습니까? 나 또는이 숫자가 나 또는 누군가에 의해 조작되지 않는다는 것을 증명해야하기 때문에 해시 함수를 사용하고 있습니다. – Lazy
해시를 원한다면 md5 또는 더 나은 것과 같은 해시를 사용하십시오. 그러나 무작위 부분이 들어오는 곳을 얻지 못합니다 ... – dandavis