generateKey method
Hashes a password
with a given salt
.
The length of this return value will be keyLength
.
See 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 numberOfBlocks = (keyLength / _blockSize).ceil();
final hmac = Hmac(hashAlgorithm, utf8.encode(password));
final key = ByteData(keyLength);
var offset = 0;
final saltBytes = utf8.encode(salt);
final saltLength = saltBytes.length;
final inputBuffer = 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);
final 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();
}