Skip to content

Commit

Permalink
Added tests
Browse files Browse the repository at this point in the history
Refactored some code
  • Loading branch information
Vanethos committed Mar 6, 2019
1 parent 44a4d86 commit 64eb00b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 87 deletions.
41 changes: 33 additions & 8 deletions lib/ui/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class MyHomePage extends StatefulWidget {

class _MyHomePageState extends State<MyHomePage> {
/// The Future that will show the Pem String
Future<String> futurePemKey;
Future<String> futureText;

/// Future to hold the reference to the KeyPair generated with PointyCastle
/// in order to extract the [crypto.PrivateKey] and [crypto.PublicKey]
Expand All @@ -30,13 +30,16 @@ class _MyHomePageState extends State<MyHomePage> {
Future<crypto.AsymmetricKeyPair<crypto.PublicKey, crypto.PrivateKey>>
getKeyPair() {
var keyHelper = DependencyProvider.of(context).getRsaKeyHelper();
return keyHelper.getRSAKeyPair(keyHelper.getSecureRandom());
return keyHelper.computeRSAKeyPair(keyHelper.getSecureRandom());
}

/// GlobalKey to be used when showing the [Snackbar] for the successful
/// copy of the Key
final key = new GlobalKey<ScaffoldState>();

/// Text Editing Controller to retrieve the text to sign
TextEditingController _controller = TextEditingController();

@override
Widget build(BuildContext context) {
return Scaffold(
Expand All @@ -59,7 +62,7 @@ class _MyHomePageState extends State<MyHomePage> {
onPressed: () {
setState(() {
// If there are any pemString being shown, then show an empty message
futurePemKey = Future.value("");
futureText = Future.value("");
// Generate a new keypair
futureKeyPair = getKeyPair();
});
Expand Down Expand Up @@ -89,7 +92,7 @@ class _MyHomePageState extends State<MyHomePage> {
setState(() {
// With the stored keypair, encode the private key to
// PKCS1 and show it
futurePemKey = Future.value(
futureText = Future.value(
DependencyProvider.of(context)
.getRsaKeyHelper()
.encodePrivateKeyToPemPKCS1(
Expand All @@ -105,14 +108,36 @@ class _MyHomePageState extends State<MyHomePage> {
setState(() {
// With the stored keypair, encode the public key to
// PKCS1 and show it
futurePemKey = Future.value(
futureText = Future.value(
DependencyProvider.of(context)
.getRsaKeyHelper()
.encodePublicKeyToPemPKCS1(
keyPair.publicKey));
});
},
)
),
TextField(
decoration: InputDecoration(
hintText: "Text to Sign"
),
controller: _controller,
),
MaterialButton(
color: Colors.black87,
child:
Text("Sign Text", style: whiteTextStyle),
onPressed: () {
setState(() {
futureText = Future.value(
DependencyProvider.of(context)
.getRsaKeyHelper()
.sign(
_controller.text,
keyPair.privateKey));
});
},
),

],
);
} else {
Expand All @@ -122,13 +147,13 @@ class _MyHomePageState extends State<MyHomePage> {
}),
),
Expanded(
flex: 3,
flex: 2,
child: Card(
child: Container(
padding: EdgeInsets.all(8),
margin: EdgeInsets.all(8),
child: FutureBuilder(
future: futurePemKey,
future: futureText,
builder: (context, snapshot) {
if (snapshot.hasData) {
return SingleChildScrollView(
Expand Down
100 changes: 22 additions & 78 deletions lib/utils/rsa_key_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ class RsaKeyHelper {
///
/// Returns a [AsymmetricKeyPair] based on the [RSAKeyGenerator] with custom parameters,
/// including a [SecureRandom]
Future<AsymmetricKeyPair<PublicKey, PrivateKey>> getRSAKeyPair(
Future<AsymmetricKeyPair<PublicKey, PrivateKey>> computeRSAKeyPair(
SecureRandom secureRandom) async {
return await compute(computeRSAKeyPair, secureRandom);
return await compute(getRsaKeyPair, secureRandom);
}

/// Generates a [SecureRandom]
Expand Down Expand Up @@ -77,6 +77,23 @@ class RsaKeyHelper {
return rsaPublicKey;
}

/// Sign plain text with Private Key
///
/// Given a plain text [String] and a [RSAPrivateKey], decrypt the text using
/// a [RSAEngine] cipher
String sign(String plainText, RSAPrivateKey privateKey) {
var signer = RSASigner(SHA256Digest(), "0609608648016503040201");
signer.init(true, PrivateKeyParameter<RSAPrivateKey>(privateKey));
return base64Encode(signer.generateSignature(createUint8ListFromString(plainText)).bytes);
}


/// Creates a [Uint8List] from a string to be signed
Uint8List createUint8ListFromString(String s) {
var codec = Utf8Codec(allowMalformed: true);
return Uint8List.fromList(codec.encode(s));
}

/// Decode Private key from PEM Format
///
/// Given a base64 encoded PEM [String] with correct headers and footers, return a
Expand Down Expand Up @@ -172,7 +189,7 @@ class RsaKeyHelper {

var version = ASN1Integer(BigInt.from(0));
var modulus = ASN1Integer(privateKey.n);
var publicExponent = ASN1Integer(BigInt.parse('65537'));
var publicExponent = ASN1Integer(privateKey.exponent);
var privateExponent = ASN1Integer(privateKey.d);
var p = ASN1Integer(privateKey.p);
var q = ASN1Integer(privateKey.q);
Expand All @@ -198,79 +215,6 @@ class RsaKeyHelper {
return """-----BEGIN PRIVATE KEY-----\r\n$dataBase64\r\n-----END PRIVATE KEY-----""";
}

/// Encode Private key to PEM Format
///
/// Given [RSAPrivateKey] returns a base64 encoded [String] with standard PEM headers and footers
String encodePrivateKeyToPemPKCS8(RSAPrivateKey privateKey) {
var version = ASN1Integer(BigInt.from(0));

var algorithmSeq = new ASN1Sequence();
var algorithmAsn1Obj = new ASN1Object.fromBytes(Uint8List.fromList(
[0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1]));
var paramsAsn1Obj =
new ASN1Object.fromBytes(Uint8List.fromList([0x5, 0x0]));
algorithmSeq.add(algorithmAsn1Obj);
algorithmSeq.add(paramsAsn1Obj);

var privateKeySeq = new ASN1Sequence();
var modulus = ASN1Integer(privateKey.n);
var publicExponent = ASN1Integer(BigInt.parse('65537'));
var privateExponent = ASN1Integer(privateKey.d);
var p = ASN1Integer(privateKey.p);
var q = ASN1Integer(privateKey.q);
var dP = privateKey.d % (privateKey.p - BigInt.from(1));
var exp1 = ASN1Integer(dP);
var dQ = privateKey.d % (privateKey.q - BigInt.from(1));
var exp2 = ASN1Integer(dQ);
var iQ = privateKey.q.modInverse(privateKey.p);
var co = ASN1Integer(iQ);

privateKeySeq.add(version);
privateKeySeq.add(modulus);
privateKeySeq.add(publicExponent);
privateKeySeq.add(privateExponent);
privateKeySeq.add(p);
privateKeySeq.add(q);
privateKeySeq.add(exp1);
privateKeySeq.add(exp2);
privateKeySeq.add(co);
var publicKeySeqOctetString =
new ASN1OctetString(Uint8List.fromList(privateKeySeq.encodedBytes));

var topLevelSeq = new ASN1Sequence();
topLevelSeq.add(version);
topLevelSeq.add(algorithmSeq);
topLevelSeq.add(publicKeySeqOctetString);
var dataBase64 = base64.encode(topLevelSeq.encodedBytes);

return """-----BEGIN PRIVATE KEY-----\r\n$dataBase64\r\n-----END PRIVATE KEY-----""";
}

/// Encode Public key to PEM Format
///
/// Given [RSAPublicKey] returns a base64 encoded [String] with standard PEM headers and footers
String encodePublicKeyToPemPKCS8(RSAPublicKey publicKey) {
var algorithmSeq = new ASN1Sequence();
var algorithmAsn1Obj = new ASN1Object.fromBytes(Uint8List.fromList(
[0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1]));
var paramsAsn1Obj =
new ASN1Object.fromBytes(Uint8List.fromList([0x5, 0x0]));
algorithmSeq.add(algorithmAsn1Obj);
algorithmSeq.add(paramsAsn1Obj);

var publicKeySeq = new ASN1Sequence();
publicKeySeq.add(ASN1Integer(publicKey.modulus));
publicKeySeq.add(ASN1Integer(publicKey.exponent));
var publicKeySeqBitString =
new ASN1BitString(Uint8List.fromList(publicKeySeq.encodedBytes));

var topLevelSeq = new ASN1Sequence();
topLevelSeq.add(algorithmSeq);
topLevelSeq.add(publicKeySeqBitString);
var dataBase64 = base64.encode(topLevelSeq.encodedBytes);
return """-----BEGIN PUBLIC KEY-----\r\n$dataBase64\r\n-----END PUBLIC KEY-----""";
}

/// Encode Public key to PEM Format
///
/// Given [RSAPublicKey] returns a base64 encoded [String] with standard PEM headers and footers
Expand All @@ -289,9 +233,9 @@ class RsaKeyHelper {
///
/// Returns a [AsymmetricKeyPair] based on the [RSAKeyGenerator] with custom parameters,
/// including a [SecureRandom]
AsymmetricKeyPair<PublicKey, PrivateKey> computeRSAKeyPair(
AsymmetricKeyPair<PublicKey, PrivateKey> getRsaKeyPair(
SecureRandom secureRandom) {
var rsapars = new RSAKeyGeneratorParameters(BigInt.from(65537), 2048, 12);
var rsapars = new RSAKeyGeneratorParameters(BigInt.from(65537), 2048, 5);
var params = new ParametersWithRandom(rsapars, secureRandom);
var keyGenerator = new RSAKeyGenerator();
keyGenerator.init(params);
Expand Down
2 changes: 1 addition & 1 deletion pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.3"
version: "1.5.4"
stack_trace:
dependency: transitive
description:
Expand Down
17 changes: 17 additions & 0 deletions test/widget_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pointycastle/key_generators/rsa_key_generator.dart';
import 'package:pointycastle/pointycastle.dart';

import 'package:rsa_key_generator/main.dart';
import 'package:rsa_key_generator/utils/rsa_key_helper.dart';

void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
Expand All @@ -27,4 +30,18 @@ void main() {
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});

test("test", () async {
RsaKeyHelper helper = RsaKeyHelper();
var keyPair = await helper.computeRSAKeyPair(helper.getSecureRandom());
print(keyPair.privateKey.toString());
});

test("Keys test", () {
var keyGenerator = new RSAKeyGenerator();
var keypair = keyGenerator.generateKeyPair();
expect(keypair, isNotNull);
});
}


0 comments on commit 64eb00b

Please sign in to comment.