SecretWallet.decode constructor
SecretWallet.decode(
- String encoded,
- String password, {
- SecretWalletEncoding encoding = SecretWalletEncoding.json,
Factory method to decode and create a SecretWallet
from an encoded string and a password.
encoded
: The encoded string containing wallet data.password
: The password used to derive the encryption key.
Returns a SecretWallet
instance decoded from the input data, or throws an error
if decoding or password validation fails.
Implementation
factory SecretWallet.decode(String encoded, String password,
{SecretWalletEncoding encoding = SecretWalletEncoding.json}) {
if (encoding == SecretWalletEncoding.cbor) {
return _decodeCbor(encoded, password);
}
final data = _toJsonEcoded(encoded, encoding: encoding);
final version = data['version'];
if (version != 3) {
throw ArgumentException("Library only supports version 3");
}
final params = data['crypto'] ?? data['Crypto'];
final String kdf = params['kdf'];
_Derivator derivator;
switch (kdf) {
case 'pbkdf2':
final derParams = params['kdfparams'] as Map<String, dynamic>;
if (derParams['prf'] != 'hmac-sha256') {
throw ArgumentException('Invalid prf only support hmac-sha256');
}
derivator = _PBDKDF2Derivator(
derParams['c'] as int,
BytesUtils.fromHexString(derParams['salt']),
derParams['dklen'] as int,
);
break;
case 'scrypt':
final derParams = params['kdfparams'] as Map<String, dynamic>;
derivator = _Scrypt(
derParams['dklen'] as int,
derParams['n'] as int,
derParams['r'] as int,
derParams['p'] as int,
BytesUtils.fromHexString(derParams['salt']),
);
break;
default:
throw ArgumentException(
'$kdf which is not supported.',
);
}
final encodedPassword = List<int>.from(StringUtils.encode(password));
final derivedKey = derivator.deriveKey(encodedPassword);
final aesKey = List<int>.from(derivedKey.sublist(0, 16));
final List<int> macBytes = derivedKey.sublist(16, 32);
final encryptedPrivateKey = BytesUtils.fromHexString(params['ciphertext']);
final derivedMac = _mac(macBytes, encryptedPrivateKey);
if (derivedMac != params['mac']) {
throw ArgumentException('wrong password or the file is corrupted');
}
if (params['cipher'] != 'aes-128-ctr') {
throw ArgumentException("only cipher aes-128-ctr is supported.");
}
final iv = BytesUtils.fromHexString(params['cipherparams']['iv']);
final encryptText = List<int>.from(encryptedPrivateKey);
final CTR ctr = CTR(AES(aesKey), iv);
final List<int> privateKey = List<int>.filled(encryptText.length, 0);
ctr.streamXOR(encryptText, privateKey);
ctr.clean();
final id = UUID.toBuffer(data['id'] as String);
return SecretWallet._(privateKey, derivator, encodedPassword, iv, id);
}