decrypt method

  1. @override
void decrypt(
  1. String password
)
override

Decrypts this entry using the given password.

Implementation

@override
void decrypt(String password) {
  if (isDecrypted()) return;

  // BKS Sealed Key structure:
  // Salt (20 bytes)
  // Iteration Count (4 bytes)
  // Ciphertext (Rest)

  if (_encryptedData == null || _encryptedData!.length < 24) {
    throw DecryptionFailureException('Invalid sealed key data length');
  }

  final data = ByteData.sublistView(_encryptedData!);
  int pos = 0;

  // Read salt (20 bytes)
  // Note: BKS V2 sometimes stores salt length?
  // BC implementation usually fixed 20 bytes for this specific internal structure
  final salt = _encryptedData!.sublist(pos, pos + 20);
  pos += 20;

  // Read iteration count
  final iterationCount = data.getUint32(pos);
  pos += 4;

  final ciphertext = _encryptedData!.sublist(pos);

  try {
    // Derive Key (192 bits = 24 bytes) and IV (64 bits = 8 bytes)

    // Actually BKS uses separate calls for Key and IV with different ID byte
    final key =
        BksKeyStore._derivePkcs12Key(password, salt, iterationCount, 24, 1);
    final iv =
        BksKeyStore._derivePkcs12Key(password, salt, iterationCount, 8, 2);

    // Decrypt 3DES-CBC
    final params = ParametersWithIV<KeyParameter>(KeyParameter(key), iv);
    final cipher = CBCBlockCipher(DESedeEngine())..init(false, params);
    final paddedCipher = PaddedBlockCipherImpl(PKCS7Padding(), cipher);

    final plaintext = paddedCipher.process(ciphertext);

    // Parse nested entry
    // The plaintext contains the BksKeyEntry fields
    // We can use _readBksKey but we need to match the signature
    // _readBksKey expects `data, pos`.

    // Note: _readBksKey reads keyType etc.
    // The sealed object content is usually the BksKeyEntry data starting AFTER the type/alias/timestamp?
    // No, it's the `SecretKey` or `PrivateKey` object serialization.
    // If it's BksKeyEntry, it includes type etc.
    // Let's assume it starts with KeyType (1 byte).

    // Warning: _readBksKey reads keyType then format then algorithm...
    // Let's try to parse it.

    final (nested, _) = BksKeyStore._readBksKey(plaintext, 0, storeType);
    nested.certChain = certChain;
    nested.alias = alias;
    nested.timestamp = timestamp;

    _nestedEntry = nested;
    _encryptedData = null; // Decrypted
  } catch (e) {
    if (e is KeystoreException) rethrow;
    throw DecryptionFailureException('BKS decryption failed: $e');
  }
}