diff --git a/lib/src/key.dart b/lib/src/key.dart index e7a9f7c..d451ba5 100644 --- a/lib/src/key.dart +++ b/lib/src/key.dart @@ -9,6 +9,8 @@ import 'platform.dart'; import 'exceptions.dart'; import 'keyspec.dart'; +import 'cipher.dart'; +import 'utils.dart'; /// This is the base class of all key types. abstract class Key { @@ -33,21 +35,21 @@ abstract class Key { /// This represents a secret key, usefull in /// algorithms like AES or BlowFish. class SecretKey extends Key { - List _supportedAlgorithms = ["AES", "Blowfish"]; - /// Creates a key from raw byte array - SecretKey.fromBytes(Uint8List bytes) : super(bytes: bytes); + SecretKey.fromBytes(Uint8List bytes, + {CipherAlgorithm algorithm: CipherAlgorithm.None}) + : super(bytes: bytes, algorithm: algorithm.name); /// Creates a key from a specific size. - SecretKey.generate(String algorithm, int size) { - if (!_supportedAlgorithms.contains(algorithm)) { - throw KeyException(algorithm + " not supported!"); - } else if (algorithm == "AES") { - List supportedSizes = [128, 192, 256]; - if (!supportedSizes.contains(size)) { + static Future generate(int size, CipherAlgorithm algorithm) async { + if (algorithm == null) { + throw KeyException("Algorithm can't be null"); + } else if (algorithm == CipherAlgorithm.AES) { + List _supportedSizes = [128, 192, 256]; + if (!_supportedSizes.contains(size)) { throw KeyException("AES must be 128, 192 or 256 bits long."); } - } else if (algorithm == "Blowfish") { + } else if (algorithm == CipherAlgorithm.BlowFish) { List supportedSizes = List.generate(52, (int index) => (index + 4) * 8); if (!supportedSizes.contains(size)) { @@ -55,15 +57,12 @@ class SecretKey extends Key { "Blowfish must be between 4 and 56 bytes (32 and 448 bits) long."); } } - _generate(algorithm, size); - } - Future _generate(String algo, int size) async { try { - _bytes = await Platform().keygen(size); - _algo = algo; - log("Generated SecretKey size: ${_bytes.length * 8} bits (${_bytes.length} bytes)", + Uint8List _key = await Platform().keygen(size); + log("Generated SecretKey size: ${_key.length * 8} bits (${_key.length} bytes)", name: "NativeCrypto"); + return SecretKey.fromBytes(_key, algorithm: algorithm); } on PlatformException catch (e) { log(e.message, name: "NativeCrypto"); throw KeyException(e); diff --git a/lib/src/sym/AES.dart b/lib/src/sym/AES.dart index 1e15347..b47f68e 100644 --- a/lib/src/sym/AES.dart +++ b/lib/src/sym/AES.dart @@ -12,15 +12,29 @@ import '../utils.dart'; /// Defines all available key sizes. enum AESKeySize { bits128, bits192, bits256 } +extension AESKeySizeExtension on AESKeySize { + int get length { + int l; + switch (this) { + case AESKeySize.bits128: + l = 128; + break; + case AESKeySize.bits192: + l = 192; + break; + case AESKeySize.bits256: + l = 256; + break; + } + return l; + } +} + class AESCipher implements Cipher { SecretKey _sk; CipherParameters _params; bool _isInit; - List _supportedCipherParams = [ - CipherParameters(BlockCipherMode.CBC, Padding.PKCS5), - ]; - @override CipherAlgorithm get algorithm => CipherAlgorithm.AES; @@ -33,34 +47,31 @@ class AESCipher implements Cipher { @override bool get isInitialized => _isInit; + @override + List get supportedParameters => [ + CipherParameters(BlockCipherMode.CBC, PlainTextPadding.PKCS5), + ]; + /// Creates an AES cipher with specified secretKey and mode/padding AESCipher(SecretKey secretKey, CipherParameters parameters) { - if (secretKey.algorithm != "AES") { - throw CipherInitException("Invalid key type: " + secretKey.algorithm); - } else if (!_supportedCipherParams.contains(parameters)) { + if (secretKey.algorithm != CipherAlgorithm.AES.name) { + List _supportedSizes = [128, 192, 256]; + if (!_supportedSizes.contains(secretKey.encoded.length)) { + throw CipherInitException("Invalid key length!"); + } + } else if (!supportedParameters.contains(parameters)) { throw CipherInitException("Invalid cipher parameters."); } + _sk = secretKey; _params = parameters; _isInit = true; } /// Generates a secret key of specified size, then creates an AES cipher. - AESCipher.generate(AESKeySize size, CipherParameters parameters) { - Map _supportedSizes = { - AESKeySize.bits128: 128, - AESKeySize.bits192: 192, - AESKeySize.bits256: 256 - }; - - if (!_supportedCipherParams.contains(parameters)) { - throw CipherInitException("Invalid cipher parameters."); - } else if (!_supportedSizes.containsKey(size)) { - throw CipherInitException("Invalid key size."); - } - - _sk = SecretKey.generate("AES", _supportedSizes[size]); - _params = parameters; - _isInit = true; + static Future generate( + AESKeySize size, CipherParameters parameters) async { + SecretKey _sk = await SecretKey.generate(size.length, CipherAlgorithm.AES); + return AESCipher(_sk, parameters); } @override