From 2b020f4fe37a412c6b0c926891a86ac313a569a4 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Wed, 15 Apr 2020 21:34:58 +0200 Subject: [PATCH] Add key size support --- lib/symmetrical_crypto.dart | 76 ++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/lib/symmetrical_crypto.dart b/lib/symmetrical_crypto.dart index 6d22be8..90a1a15 100644 --- a/lib/symmetrical_crypto.dart +++ b/lib/symmetrical_crypto.dart @@ -2,19 +2,26 @@ // Author: Hugo Pointcheval import 'dart:typed_data'; -import 'package:native_crypto/native_crypto.dart'; +import 'package:native_crypto/src/native_crypto.dart'; import 'package:native_crypto/src/exceptions.dart'; +/// Defines all available key sizes. enum KeySize { bits128, bits192, bits256 } + +/// Defines all available ciphers. enum Cipher { AES } /// AES Helper /// /// You can generate AES keys, encrypt and decrypt data. class AES { + /// This key is used for encryption and decryption. Uint8List key; + /// Check if the AES object is intialized with a valid key before perform any operation. bool isInitialized = false; + + /// Defines the size of the generated or passed key. KeySize keySize; /// You can pass a key in constructor. @@ -28,6 +35,7 @@ class AES { } } + /// [Private] /// Tests if the key is valid. /// /// The key must be 128, 192 or 256 bits long. @@ -53,13 +61,31 @@ class AES { } /// Generate an AES key. - init(KeySize keySize) async { + /// + /// You can specify a `keySize`. Default is 256 bits. + /// Return `null` if the key is already set. + init({KeySize keySize}) async { if (this.key != null) return null; - if (keySize != KeySize.bits256) - throw NotImplementedException('This key size is not implemented yet.'); + int size; - this.key = await NativeCrypto().symKeygen(); + switch (keySize) { + case KeySize.bits128: + size = 128; + break; + case KeySize.bits192: + size = 192; + break; + case KeySize.bits256: + size = 256; + break; + default: + // Default size = 256 bits + size = 256; + break; + } + + this.key = await NativeCrypto().symKeygen(size); try { bool isValidKey = _testKey(); this.isInitialized = isValidKey; @@ -69,11 +95,13 @@ class AES { } } - /// Encrypt data - /// - /// Returns an `Encrypted` object. + /// Encrypts data. + /// + /// Takes `Uint8List` data as parameter. + /// And returns an `Encrypted` object. Future encrypt(Uint8List data) async { - if (!this.isInitialized) throw EncryptionException('Instance not initialized.'); + if (!this.isInitialized) + throw EncryptionException('Instance not initialized.'); List encryptedPayload = await NativeCrypto().symEncrypt(data, this.key); Encrypted encrypted = Encrypted.fromList(Cipher.AES, encryptedPayload); @@ -81,8 +109,13 @@ class AES { return encrypted; } + /// Decrypts data. + /// + /// Takes `Encrypted` object as parameter. + /// And returns plain text data as `Uint8List`. Future decrypt(Encrypted encrypted) async { - if (!this.isInitialized) throw DecryptionException('Instance not initialized.'); + if (!this.isInitialized) + throw DecryptionException('Instance not initialized.'); Uint8List decryptedPayload = await NativeCrypto().symDecrypt(encrypted.toList(), this.key); return decryptedPayload; @@ -92,21 +125,36 @@ class AES { /// Contains data of an encrypted payload. /// More practical than a list. class Encrypted { + /// Contains encryption algorithm. Cipher cipher; + + /// Contains encrypted bytes. Uint8List cipherText; + + /// Contains IV used for encryption. + /// + /// Needed for decryption. Uint8List iv; + + /// Contains MAC. + /// + /// Used in decryption to authenticate the data. Uint8List mac; - Encrypted(); - + /// Creates an encrypted from payload `List`. Encrypted.fromList(this.cipher, List encryptedPayload) { this.mac = encryptedPayload[0].sublist(0, 32); - this.cipherText = encryptedPayload[0].sublist(32, encryptedPayload[0].length); + this.cipherText = + encryptedPayload[0].sublist(32, encryptedPayload[0].length); this.iv = encryptedPayload[1]; } + /// Returns a payload `List` from this encrypted. List toList() { - List encryptedPayload = [Uint8List.fromList(this.mac + this.cipherText), this.iv]; + List encryptedPayload = [ + Uint8List.fromList(this.mac + this.cipherText), + this.iv + ]; return encryptedPayload; } }