generateKey method
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 PBKDF2Exception('Derived key too long');
}
final int numberOfBlocks = (keyLength / _blockSize).ceil();
final Hmac hmac = Hmac(hashAlgorithm, utf8.encode(password));
final ByteData key = ByteData(keyLength);
int offset = 0;
final List<int> saltBytes = utf8.encode(salt);
final int saltLength = saltBytes.length;
final ByteData inputBuffer = ByteData(saltBytes.length + 4)
..buffer.asUint8List().setRange(0, saltBytes.length, saltBytes);
for (int blockNumber = 1; blockNumber <= numberOfBlocks; blockNumber++) {
inputBuffer
..setUint8(saltLength, blockNumber >> 24)
..setUint8(saltLength + 1, blockNumber >> 16)
..setUint8(saltLength + 2, blockNumber >> 8)
..setUint8(saltLength + 3, blockNumber);
final Uint8List block =
_XORDigestSink.generate(inputBuffer, hmac, rounds);
int blockLength = _blockSize;
if (offset + blockLength > keyLength) {
blockLength = keyLength - offset;
}
key.buffer.asUint8List().setRange(offset, offset + blockLength, block);
offset += blockLength;
}
return key.buffer.asUint8List();
}