generateKey method

List<int> generateKey(
  1. String password,
  2. String salt,
  3. int rounds,
  4. int keyLength,
)

Hashes a password with a given salt.

The length of this return value will be keyLength.

See Salt.generateAsBase64String for generating a random salt.

See also generateBase64Key, which base64 encodes the key returned from this method for storage.

Implementation

List<int> generateKey(
    String password, String salt, int rounds, int keyLength) {
  if (keyLength > (pow(2, 32) - 1) * _blockSize!) {
    throw new PBKDF2Exception("Derived key too long");
  }

  var numberOfBlocks = (keyLength / _blockSize!).ceil();
  var hmac = new Hmac(hashAlgorithm, utf8.encode(password));
  var key = new ByteData(keyLength);
  var offset = 0;

  var saltBytes = utf8.encode(salt);
  var saltLength = saltBytes.length;
  var inputBuffer = new ByteData(saltBytes.length + 4)
    ..buffer.asUint8List().setRange(0, saltBytes.length, saltBytes);

  for (var blockNumber = 1; blockNumber <= numberOfBlocks; blockNumber++) {
    inputBuffer.setUint8(saltLength, blockNumber >> 24);
    inputBuffer.setUint8(saltLength + 1, blockNumber >> 16);
    inputBuffer.setUint8(saltLength + 2, blockNumber >> 8);
    inputBuffer.setUint8(saltLength + 3, blockNumber);

    var block = _XORDigestSink.generate(inputBuffer, hmac, rounds);
    var blockLength = _blockSize;
    if (offset + (blockLength!) > keyLength) {
      blockLength = keyLength - offset;
    }
    key.buffer.asUint8List().setRange(offset, offset + blockLength, block);

    offset += blockLength;
  }

  return key.buffer.asUint8List();
}