unwrap static method
Implementation
static K4LocalKey unwrap(String wrappedKey, K4LocalKey wrappingKey) {
if (!wrappedKey.startsWith(PaserkKey.k4LocalWrapPiePrefix)) {
throw ArgumentError('Invalid k4.local-wrap format');
}
final payload = Uint8List.fromList(
SafeBase64.decode(
wrappedKey.substring(PaserkKey.k4LocalWrapPiePrefix.length),
),
);
if (payload.length < tagLength + nonceLength + K4LocalKey.keyLength) {
throw ArgumentError('Invalid wrapped key length');
}
final tag = payload.sublist(0, tagLength);
final nonce = payload.sublist(tagLength, tagLength + nonceLength);
final ciphertext = payload.sublist(tagLength + nonceLength, payload.length);
final authKey = _deriveAuthKey(wrappingKey.rawBytes, nonce);
final expectedTag = _calculateTag(nonce, ciphertext, authKey);
if (!_constantTimeEquals(tag, expectedTag)) {
throw ArgumentError('Invalid authentication tag');
}
final derived = _deriveEncryptionMaterial(wrappingKey.rawBytes, nonce);
final encryptionKey = derived.sublist(0, 32);
final xchachaNonce = derived.sublist(32);
final cipher = XChaCha20();
cipher.init(
false,
ParametersWithIV<KeyParameter>(
KeyParameter(Uint8List.fromList(encryptionKey)),
Uint8List.fromList(xchachaNonce),
),
);
final decrypted = cipher.process(ciphertext);
if (decrypted.length != K4LocalKey.keyLength) {
throw ArgumentError('Decrypted key has invalid length');
}
return K4LocalKey(decrypted);
}