From e4d71b116b2d37ee1e753521a1a0b19dbd56e89d Mon Sep 17 00:00:00 2001 From: Hoylen Sue Date: Sun, 8 May 2022 11:41:01 +1000 Subject: [PATCH 1/2] Tutorials updated to be consistent with current coding conventions. --- tutorials/aes-cbc.md | 22 +++++++++++----- tutorials/digest.md | 18 +++++++------ tutorials/examples/README.md | 23 ++++++++++++++++- tutorials/examples/aes-cbc-direct.dart | 32 ++++++++---------------- tutorials/examples/aes-cbc-registry.dart | 3 ++- tutorials/examples/digest-direct.dart | 6 ++++- tutorials/examples/hmac-direct.dart | 14 +++++++---- tutorials/examples/rsa-demo.dart | 7 +++--- tutorials/hmac.md | 6 ++--- tutorials/rsa.md | 19 ++++++++------ 10 files changed, 93 insertions(+), 57 deletions(-) diff --git a/tutorials/aes-cbc.md b/tutorials/aes-cbc.md index 14136e43..36ab9347 100644 --- a/tutorials/aes-cbc.md +++ b/tutorials/aes-cbc.md @@ -42,10 +42,15 @@ import 'dart:typed_data'; import "package:pointycastle/export.dart"; -Uint8List aesCbcEncrypt(Uint8List key, Uint8List iv, Uint8List paddedPlaintext) { +Uint8List aesCbcEncrypt( + Uint8List key, Uint8List iv, Uint8List paddedPlaintext) { + assert([128, 192, 256].contains(key.length * 8)); + assert(128 == iv.length * 8); + assert(128 == paddedPlaintext.length * 8); + // Create a CBC block cipher with AES, and initialize with key and IV - final cbc = CBCBlockCipher(AESFastEngine()) + final cbc = CBCBlockCipher(AESEngine()) ..init(true, ParametersWithIV(KeyParameter(key), iv)); // true=encrypt // Encrypt the plaintext block-by-block @@ -62,9 +67,13 @@ Uint8List aesCbcEncrypt(Uint8List key, Uint8List iv, Uint8List paddedPlaintext) } Uint8List aesCbcDecrypt(Uint8List key, Uint8List iv, Uint8List cipherText) { + assert([128, 192, 256].contains(key.length * 8)); + assert(128 == iv.length * 8); + assert(128 == cipherText.length * 8); + // Create a CBC block cipher with AES, and initialize with key and IV - final cbc = CBCBlockCipher(AESFastEngine()) + final cbc = CBCBlockCipher(AESEngine()) ..init(false, ParametersWithIV(KeyParameter(key), iv)); // false=decrypt // Decrypt the cipherText block-by-block @@ -85,12 +94,13 @@ The _key_ must be exactly 128-bits, 192-bits or 256-bits (i.e. 16, 24 or 32 bytes). This is what determines whether AES-128, AES-192 or AES-256 is being performed. -The _iv_ must be exactly 128-bites (16 bytes) long, which is the AES +The _iv_ must be exactly 128-bits (16 bytes) long, which is the AES block size. The _paddedPlainText_ must be a multiple of the block size (128-bits). If the data being encrypted is not the correct length, it -must be padded before it can be processed by AES. +must be padded before it can be processed by AES. The implementations +of padding algorithms in Pointy Castle can be used for this. ## Details @@ -112,7 +122,7 @@ If the registry is not used, invoke the block cipher's constructor, passing in the AES implementation as a parameter. ```dart -final aesCbc = CBCBlockCipher(AESFastEngine()); +final aesCbc = CBCBlockCipher(AESEngine()); ``` ### Initialize with key and IV diff --git a/tutorials/digest.md b/tutorials/digest.md index 0bcbbc17..ef5b55e8 100644 --- a/tutorials/digest.md +++ b/tutorials/digest.md @@ -31,17 +31,19 @@ import 'dart:typed_data'; import "package:pointycastle/export.dart"; Uint8List sha256Digest(Uint8List dataToDigest) { - - final d = new SHA256Digest(); + final d = SHA256Digest(); return d.process(dataToDigest); } void main(List args) { - for (final data in args) { + final valuesToDigest = (args.isNotEmpty) ? args : ['Hello world!']; + + for (final data in valuesToDigest) { print('Data: "$data"'); - final hashValue = sha256Digest(utf8.encode(data)); - print('SHA-256: $hashValue'); + final hash = sha256Digest(utf8.encode(data) as Uint8List); + print('SHA-256: $hash'); + print('SHA-256: ${bin2hex(hash)}'); // output in hexadecimal } } ``` @@ -59,7 +61,7 @@ If using the registry, invoke the `Digest` factory with the name of the digest algorithm. ```dart -final d = new Digest("SHA-256"); +final d = Digest("SHA-256"); ``` Possible names include: "MD2", "MD4", "MD5", "RIPEMD-128", @@ -81,7 +83,7 @@ If the registery is not used, invoke the digest implementation's constructor. ```dart -final d = new SHA256Digest(); // SHA-256 +final d = SHA256Digest(); // SHA-256 ``` All of the available digest classes of are listed as the implementers @@ -153,7 +155,7 @@ required if previously provided data is abandoned. final part1 = utf8.encode('Hello '); final part2 = utf8.encode('world!'); -final d = new SHA256Digest(); +final d = SHA256Digest(); final hash = Uint8List(d.digestSize); // Without rest diff --git a/tutorials/examples/README.md b/tutorials/examples/README.md index 90f68a02..0c7b4d61 100644 --- a/tutorials/examples/README.md +++ b/tutorials/examples/README.md @@ -7,4 +7,25 @@ used in the tutorials. They are not officially a part of the tutorials, and are only provided on an as-is basis. -All of them accept the "-h" or "--help" option. +## Running the examples + +Run "dart pub get" in the parent directory, and then run the example Dart +Dart programs. For example: + +```sh +dart aes-cbc-direct.dart +dart digest-direct.dart "foobar" +dart rsa-demo.dart +``` + +All of these example programs accept the "-h" or "--help" option. + +## Checking the text in the tutorials + +Fragments of the Dart code are copied into the MarkDown tutorial files +in the parent directory. + +The fragments between comment lines containing "BEGIN EXAMPLE" and +"END EXAMPLE" should appear literally the same in the MarkDown file. +Other fragments have been modified to make them more readable in the +tutorial and more functional in the example code. diff --git a/tutorials/examples/aes-cbc-direct.dart b/tutorials/examples/aes-cbc-direct.dart index f182dec0..2a8000b3 100644 --- a/tutorials/examples/aes-cbc-direct.dart +++ b/tutorials/examples/aes-cbc-direct.dart @@ -10,22 +10,16 @@ import 'package:pointycastle/export.dart'; import 'package:pointycastle/src/platform_check/platform_check.dart'; // Code convention: variable names starting with underscores are examples only, -// and should be implementated according to the needs of the program. +// and should be implemented according to the needs of the program. //---------------------------------------------------------------- +// BEGIN EXAMPLE in "../aes-cbc.md" Uint8List aesCbcEncrypt( Uint8List key, Uint8List iv, Uint8List paddedPlaintext) { - if (![128, 192, 256].contains(key.length * 8)) { - throw ArgumentError.value(key, 'key', 'invalid key length for AES'); - } - if (iv.length * 8 != 128) { - throw ArgumentError.value(iv, 'iv', 'invalid IV length for AES'); - } - if (paddedPlaintext.length * 8 % 128 != 0) { - throw ArgumentError.value( - paddedPlaintext, 'paddedPlaintext', 'invalid length for AES'); - } + assert([128, 192, 256].contains(key.length * 8)); + assert(128 == iv.length * 8); + assert(128 == paddedPlaintext.length * 8); // Create a CBC block cipher with AES, and initialize with key and IV @@ -44,19 +38,11 @@ Uint8List aesCbcEncrypt( return cipherText; } -//---------------------------------------------------------------- Uint8List aesCbcDecrypt(Uint8List key, Uint8List iv, Uint8List cipherText) { - if (![128, 192, 256].contains(key.length * 8)) { - throw ArgumentError.value(key, 'key', 'invalid key length for AES'); - } - if (iv.length * 8 != 128) { - throw ArgumentError.value(iv, 'iv', 'invalid IV length for AES'); - } - if (cipherText.length * 8 % 128 != 0) { - throw ArgumentError.value( - cipherText, 'cipherText', 'invalid length for AES'); - } + assert([128, 192, 256].contains(key.length * 8)); + assert(128 == iv.length * 8); + assert(128 == cipherText.length * 8); // Create a CBC block cipher with AES, and initialize with key and IV @@ -76,6 +62,8 @@ Uint8List aesCbcDecrypt(Uint8List key, Uint8List iv, Uint8List cipherText) { return paddedPlainText; } +// END EXAMPLE + //================================================================ // Supporting functions // diff --git a/tutorials/examples/aes-cbc-registry.dart b/tutorials/examples/aes-cbc-registry.dart index 4797c3ef..2129c8c3 100644 --- a/tutorials/examples/aes-cbc-registry.dart +++ b/tutorials/examples/aes-cbc-registry.dart @@ -10,7 +10,7 @@ import 'package:pointycastle/pointycastle.dart'; import 'package:pointycastle/src/platform_check/platform_check.dart'; // Code convention: variable names starting with underscores are examples only, -// and should be implementated according to the needs of the program. +// and should be implemented according to the needs of the program. //---------------------------------------------------------------- @@ -44,6 +44,7 @@ Uint8List aesCbcEncrypt( return cipherText; } + //---------------------------------------------------------------- Uint8List aesCbcDecrypt(Uint8List key, Uint8List iv, Uint8List cipherText) { diff --git a/tutorials/examples/digest-direct.dart b/tutorials/examples/digest-direct.dart index 5352b817..d2a997c6 100644 --- a/tutorials/examples/digest-direct.dart +++ b/tutorials/examples/digest-direct.dart @@ -19,12 +19,16 @@ import 'dart:typed_data'; import 'package:pointycastle/export.dart'; +// BEGIN EXAMPLE in "../digest.md" + Uint8List sha256Digest(Uint8List dataToDigest) { final d = SHA256Digest(); return d.process(dataToDigest); } +// END EXAMPLE + void main(List args) { if (args.contains('-h') || args.contains('--help')) { print('Usage: digest-direct {stringsToDigest}'); @@ -35,7 +39,7 @@ void main(List args) { for (final data in valuesToDigest) { print('Data: "$data"'); - final hash = sha256Digest(Uint8List.fromList(utf8.encode(data))); + final hash = sha256Digest(utf8.encode(data) as Uint8List); print('SHA-256: $hash'); print('SHA-256: ${bin2hex(hash)}'); // output in hexadecimal } diff --git a/tutorials/examples/hmac-direct.dart b/tutorials/examples/hmac-direct.dart index f4036e26..82342453 100644 --- a/tutorials/examples/hmac-direct.dart +++ b/tutorials/examples/hmac-direct.dart @@ -13,14 +13,17 @@ import 'dart:typed_data'; import 'package:pointycastle/export.dart'; -Uint8List hmacSha1(Uint8List hmacKey, Uint8List data) { - final hmac = - HMac(SHA256Digest(), 64) // HMAC SHA-256 must use block length of 64 - ..init(KeyParameter(hmacKey)); +// BEGIN EXAMPLE in "../hmac.md" + +Uint8List hmacSha256(Uint8List hmacKey, Uint8List data) { + final hmac = HMac(SHA256Digest(), 64) // HMAC SHA-256: block must be 64 bytes + ..init(KeyParameter(hmacKey)); return hmac.process(data); } +// END EXAMPLE + void hmacWithOtherDigestAlgorithms(Uint8List hmacKey, Uint8List data) { final hmacSha256 = HMac(SHA256Digest(), 64); final hmacSha512 = HMac(SHA512Digest(), 128); @@ -45,7 +48,8 @@ void main(List args) { final data = utf8.encode(args[1]); // second argument is the data print('Data: "${args[1]}"'); - final hmacValue = hmacSha1(Uint8List.fromList(key), Uint8List.fromList(data)); + final hmacValue = + hmacSha256(Uint8List.fromList(key), Uint8List.fromList(data)); //print('HMAC SHA-1: $hmacValue'); print('HMAC SHA-1: ${bin2hex(hmacValue)}'); diff --git a/tutorials/examples/rsa-demo.dart b/tutorials/examples/rsa-demo.dart index 4fb2348c..60fc3257 100644 --- a/tutorials/examples/rsa-demo.dart +++ b/tutorials/examples/rsa-demo.dart @@ -8,7 +8,6 @@ /// Invoke with "-l" to use longer plaintext. import 'dart:convert'; -import 'dart:math'; import 'dart:typed_data'; // For using the registry: @@ -53,7 +52,7 @@ AsymmetricKeyPair generateRSAkeyPair( final pair = keyGen.generateKeyPair(); - // Examine the generated key-pair + // Cast the generated key pair into the RSA key types final myPublic = pair.publicKey as RSAPublicKey; final myPrivate = pair.privateKey as RSAPrivateKey; @@ -87,6 +86,7 @@ Uint8List rsaSign(RSAPrivateKey privateKey, Uint8List dataToSign) { // corresponding to the digest algorithm, otherwise the signature won't // verify. + // initialize with true, which means sign signer.init(true, PrivateKeyParameter(privateKey)); final sig = signer.generateSignature(dataToSign); @@ -99,14 +99,15 @@ Uint8List rsaSign(RSAPrivateKey privateKey, Uint8List dataToSign) { bool rsaVerify( RSAPublicKey publicKey, Uint8List signedData, Uint8List signature) { - final sig = RSASignature(signature); //final signer = Signer('SHA-256/RSA'); // Get using registry + final sig = RSASignature(signature); final verifier = RSASigner(SHA256Digest(), '0609608648016503040201'); // See _DIGEST_IDENTIFIER_HEXES in RSASigner for correct hex values to use // IMPORTANT: the correct digest identifier hex value must be used, // corresponding to the digest algorithm, otherwise the signature won't // verify. + // initialize with false, which means verify verifier.init(false, PublicKeyParameter(publicKey)); return verifier.verifySignature(signedData, sig); diff --git a/tutorials/hmac.md b/tutorials/hmac.md index 250cb668..c8e2a696 100644 --- a/tutorials/hmac.md +++ b/tutorials/hmac.md @@ -25,7 +25,7 @@ import 'dart:typed_data'; import "package:pointycastle/export.dart"; Uint8List hmacSha256(Uint8List hmacKey, Uint8List data) { - final hmac = HMac(SHA256Digest(), 64) // for HMAC SHA-256, block length must be 64 + final hmac = HMac(SHA256Digest(), 64) // HMAC SHA-256: block must be 64 bytes ..init(KeyParameter(hmacKey)); return hmac.process(data); @@ -34,7 +34,7 @@ Uint8List hmacSha256(Uint8List hmacKey, Uint8List data) { void main(List args) { final key = utf8.encode(args[0]); // first argument is the key final data = utf8.encode(args[1]); // second argument is the data - + final hmacValue = hmacSha256(key, data); print('HMAC SHA-256: $hmacValue'); } @@ -51,7 +51,7 @@ HMAC algorithm. The name of the HMAC algorithm is the name of the digest algorithm followed by "/HMAC" (e.g. "SHA-1/HMAC"). ```dart -final hmac = new Mac("SHA-256/HMAC"); +final hmac = Mac("SHA-256/HMAC"); ``` #### Without the registry diff --git a/tutorials/rsa.md b/tutorials/rsa.md index 74e77100..8912a449 100644 --- a/tutorials/rsa.md +++ b/tutorials/rsa.md @@ -38,10 +38,12 @@ AsymmetricKeyPair generateRSAkeyPair( {int bitLength = 2048}) { // Create an RSA key generator and initialize it - final keyGen = RSAKeyGenerator() - ..init(ParametersWithRandom( - RSAKeyGeneratorParameters(BigInt.parse('65537'), bitLength, 64), - secureRandom)); + // final keyGen = KeyGenerator('RSA'); // Get using registry + final keyGen = RSAKeyGenerator(); + + keyGen.init(ParametersWithRandom( + RSAKeyGeneratorParameters(BigInt.parse('65537'), bitLength, 64), + secureRandom)); // Use the generator @@ -168,10 +170,11 @@ using SHA-256 as the digest algorithm: import "package:pointycastle/export.dart"; Uint8List rsaSign(RSAPrivateKey privateKey, Uint8List dataToSign) { - + //final signer = Signer('SHA-256/RSA'); // Get using registry final signer = RSASigner(SHA256Digest(), '0609608648016503040201'); - signer.init(true, PrivateKeyParameter(privateKey)); // true=sign + // initialize with true, which means sign + signer.init(true, PrivateKeyParameter(privateKey)); final sig = signer.generateSignature(dataToSign); @@ -180,11 +183,13 @@ Uint8List rsaSign(RSAPrivateKey privateKey, Uint8List dataToSign) { bool rsaVerify( RSAPublicKey publicKey, Uint8List signedData, Uint8List signature) { + //final signer = Signer('SHA-256/RSA'); // Get using registry final sig = RSASignature(signature); final verifier = RSASigner(SHA256Digest(), '0609608648016503040201'); - verifier.init(false, PublicKeyParameter(publicKey)); // false=verify + // initialize with false, which means verify + verifier.init(false, PublicKeyParameter(publicKey)); try { return verifier.verifySignature(signedData, sig); From 4675fdcd7e5670c03ef2ce74c222322f17e7ef4c Mon Sep 17 00:00:00 2001 From: Hoylen Sue Date: Mon, 16 May 2022 09:49:59 +1000 Subject: [PATCH 2/2] Changed "pub" command to "dart pub". --- .github/workflows/chrome.workflow.yml | 2 +- .github/workflows/node.workflow.yml | 2 +- .github/workflows/vm.workflow.yml | 2 +- .gitlab-ci.yml | 13 ++++++++----- .travis.yml | 6 +++--- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/chrome.workflow.yml b/.github/workflows/chrome.workflow.yml index 50aa4371..b8e3f9fe 100644 --- a/.github/workflows/chrome.workflow.yml +++ b/.github/workflows/chrome.workflow.yml @@ -31,4 +31,4 @@ jobs: run: dart pub get - name: Test chrome - run: pub run test -p chrome \ No newline at end of file + run: dart pub run test -p chrome diff --git a/.github/workflows/node.workflow.yml b/.github/workflows/node.workflow.yml index d0fd4bfd..9694ba9f 100644 --- a/.github/workflows/node.workflow.yml +++ b/.github/workflows/node.workflow.yml @@ -31,4 +31,4 @@ jobs: run: dart pub get - name: Test node - run: pub run test -p node \ No newline at end of file + run: dart pub run test -p node diff --git a/.github/workflows/vm.workflow.yml b/.github/workflows/vm.workflow.yml index 87ff34a5..791b7e1f 100644 --- a/.github/workflows/vm.workflow.yml +++ b/.github/workflows/vm.workflow.yml @@ -31,4 +31,4 @@ jobs: run: dart pub get - name: Test dartvm - run: pub run test -p vm \ No newline at end of file + run: dart pub run test -p vm diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 649c9969..24a4b302 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,24 +10,27 @@ test-code-vm: stage: test script: - "export PATH=$PATH:/usr/lib/dart/bin:$HOME/.pub-cache/bin; \ - pub get; pub run test;" + dart pub get; \ + dart pub run test;" test-code-node: stage: test script: - "export PATH=$PATH:/usr/lib/dart/bin:$HOME/.pub-cache/bin; \ - pub get; pub run test --timeout 15m -p node" + dart pub get; \ + dart pub run test --timeout 15m -p node" test-code-chrome: stage: test script: - "export PATH=$PATH:/usr/lib/dart/bin:$HOME/.pub-cache/bin; \ - pub get; pub run test --timeout 15m -p chrome" + dart pub get; \ + dart pub run test --timeout 15m -p chrome" score-pana: stage: score script: - "export PATH=$PATH:/usr/lib/dart/bin:$HOME/.pub-cache/bin; \ - pub get; \ - pub global activate pana; \ + dart pub get; \ + dart pub global activate pana; \ pana ." diff --git a/.travis.yml b/.travis.yml index b675b0d4..71a8cea5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,6 @@ language: dart dart: - stable script: - - pub run test - - pub global activate pana - - pana . \ No newline at end of file + - dart pub run test + - dart pub global activate pana + - dart pana .