Skip to content

Instantly share code, notes, and snippets.

@blluv
Created April 9, 2022 17:44
Show Gist options
  • Save blluv/9635c974c1db22d0affc4b465f903c76 to your computer and use it in GitHub Desktop.
Save blluv/9635c974c1db22d0affc4b465f903c76 to your computer and use it in GitHub Desktop.
pkcs12 key derive
Uint8List deriveKey(
List<int> password, List<int> salt, int keySize, int iterations) {
var np = Uint8List(password.length * 2 + 2);
for (var i = 0; i < password.length; i++) {
np[i * 2] = 0;
np[i * 2 + 1] = password[i];
}
const sha1BlockSize = 64;
const sha1DigestSize = 20;
var D = Uint8List(sha1BlockSize);
for (var i = 0; i < D.length; i++) {
D[i] = 1;
}
var S = Uint8List(sha1BlockSize *
((salt.length + sha1BlockSize - 1) / sha1BlockSize).floor());
for (var i = 0; i < S.length; i++) {
S[i] = salt[i % salt.length];
}
var P = Uint8List(sha1BlockSize *
((np.length + sha1BlockSize - 1) / sha1BlockSize).floor());
for (var i = 0; i < P.length; i++) {
P[i] = np[i % np.length];
}
var I = S + P;
var B = Uint8List(sha1BlockSize);
var c = ((keySize + sha1DigestSize - 1) / sha1DigestSize).floor();
var key = Uint8List(keySize);
for (var i = 1; i < c + 1; i++) {
Digest d = sha1.convert(D + I);
for (var j = 1; j < iterations; j++) {
d = sha1.convert(d.bytes);
}
for (int j = 0; j < B.length; j++) {
B[j] = d.bytes[j % d.bytes.length];
}
for (int j = 0; j < (I.length / sha1BlockSize).floor(); j++) {
var aOff = j * sha1BlockSize;
var x = (B[B.length - 1] & 0xff) + (I[aOff + B.length - 1] & 0xff) + 1;
I[aOff + B.length - 1] = x % 256;
x = x >> 8;
for (int jj = B.length - 2; jj >= 0; jj--) {
x = x + (B[i] & 0xff) + (I[aOff + i] & 0xff);
I[aOff + i] = x % 256;
x = x >> 8;
}
}
var start = (i - 1) * sha1DigestSize;
if (i == c) {
key.setRange(start, keySize, d.bytes);
} else {
key.setRange(start, start + d.bytes.length, d.bytes);
}
}
return key;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment