Skip to content

Commit 64eb00b

Browse files
committed
Added tests
Refactored some code
1 parent 44a4d86 commit 64eb00b

File tree

4 files changed

+73
-87
lines changed

4 files changed

+73
-87
lines changed

lib/ui/home_page.dart

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class MyHomePage extends StatefulWidget {
1515

1616
class _MyHomePageState extends State<MyHomePage> {
1717
/// The Future that will show the Pem String
18-
Future<String> futurePemKey;
18+
Future<String> futureText;
1919

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

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

40+
/// Text Editing Controller to retrieve the text to sign
41+
TextEditingController _controller = TextEditingController();
42+
4043
@override
4144
Widget build(BuildContext context) {
4245
return Scaffold(
@@ -59,7 +62,7 @@ class _MyHomePageState extends State<MyHomePage> {
5962
onPressed: () {
6063
setState(() {
6164
// If there are any pemString being shown, then show an empty message
62-
futurePemKey = Future.value("");
65+
futureText = Future.value("");
6366
// Generate a new keypair
6467
futureKeyPair = getKeyPair();
6568
});
@@ -89,7 +92,7 @@ class _MyHomePageState extends State<MyHomePage> {
8992
setState(() {
9093
// With the stored keypair, encode the private key to
9194
// PKCS1 and show it
92-
futurePemKey = Future.value(
95+
futureText = Future.value(
9396
DependencyProvider.of(context)
9497
.getRsaKeyHelper()
9598
.encodePrivateKeyToPemPKCS1(
@@ -105,14 +108,36 @@ class _MyHomePageState extends State<MyHomePage> {
105108
setState(() {
106109
// With the stored keypair, encode the public key to
107110
// PKCS1 and show it
108-
futurePemKey = Future.value(
111+
futureText = Future.value(
109112
DependencyProvider.of(context)
110113
.getRsaKeyHelper()
111114
.encodePublicKeyToPemPKCS1(
112115
keyPair.publicKey));
113116
});
114117
},
115-
)
118+
),
119+
TextField(
120+
decoration: InputDecoration(
121+
hintText: "Text to Sign"
122+
),
123+
controller: _controller,
124+
),
125+
MaterialButton(
126+
color: Colors.black87,
127+
child:
128+
Text("Sign Text", style: whiteTextStyle),
129+
onPressed: () {
130+
setState(() {
131+
futureText = Future.value(
132+
DependencyProvider.of(context)
133+
.getRsaKeyHelper()
134+
.sign(
135+
_controller.text,
136+
keyPair.privateKey));
137+
});
138+
},
139+
),
140+
116141
],
117142
);
118143
} else {
@@ -122,13 +147,13 @@ class _MyHomePageState extends State<MyHomePage> {
122147
}),
123148
),
124149
Expanded(
125-
flex: 3,
150+
flex: 2,
126151
child: Card(
127152
child: Container(
128153
padding: EdgeInsets.all(8),
129154
margin: EdgeInsets.all(8),
130155
child: FutureBuilder(
131-
future: futurePemKey,
156+
future: futureText,
132157
builder: (context, snapshot) {
133158
if (snapshot.hasData) {
134159
return SingleChildScrollView(

lib/utils/rsa_key_helper.dart

Lines changed: 22 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ class RsaKeyHelper {
1212
///
1313
/// Returns a [AsymmetricKeyPair] based on the [RSAKeyGenerator] with custom parameters,
1414
/// including a [SecureRandom]
15-
Future<AsymmetricKeyPair<PublicKey, PrivateKey>> getRSAKeyPair(
15+
Future<AsymmetricKeyPair<PublicKey, PrivateKey>> computeRSAKeyPair(
1616
SecureRandom secureRandom) async {
17-
return await compute(computeRSAKeyPair, secureRandom);
17+
return await compute(getRsaKeyPair, secureRandom);
1818
}
1919

2020
/// Generates a [SecureRandom]
@@ -77,6 +77,23 @@ class RsaKeyHelper {
7777
return rsaPublicKey;
7878
}
7979

80+
/// Sign plain text with Private Key
81+
///
82+
/// Given a plain text [String] and a [RSAPrivateKey], decrypt the text using
83+
/// a [RSAEngine] cipher
84+
String sign(String plainText, RSAPrivateKey privateKey) {
85+
var signer = RSASigner(SHA256Digest(), "0609608648016503040201");
86+
signer.init(true, PrivateKeyParameter<RSAPrivateKey>(privateKey));
87+
return base64Encode(signer.generateSignature(createUint8ListFromString(plainText)).bytes);
88+
}
89+
90+
91+
/// Creates a [Uint8List] from a string to be signed
92+
Uint8List createUint8ListFromString(String s) {
93+
var codec = Utf8Codec(allowMalformed: true);
94+
return Uint8List.fromList(codec.encode(s));
95+
}
96+
8097
/// Decode Private key from PEM Format
8198
///
8299
/// Given a base64 encoded PEM [String] with correct headers and footers, return a
@@ -172,7 +189,7 @@ class RsaKeyHelper {
172189

173190
var version = ASN1Integer(BigInt.from(0));
174191
var modulus = ASN1Integer(privateKey.n);
175-
var publicExponent = ASN1Integer(BigInt.parse('65537'));
192+
var publicExponent = ASN1Integer(privateKey.exponent);
176193
var privateExponent = ASN1Integer(privateKey.d);
177194
var p = ASN1Integer(privateKey.p);
178195
var q = ASN1Integer(privateKey.q);
@@ -198,79 +215,6 @@ class RsaKeyHelper {
198215
return """-----BEGIN PRIVATE KEY-----\r\n$dataBase64\r\n-----END PRIVATE KEY-----""";
199216
}
200217

201-
/// Encode Private key to PEM Format
202-
///
203-
/// Given [RSAPrivateKey] returns a base64 encoded [String] with standard PEM headers and footers
204-
String encodePrivateKeyToPemPKCS8(RSAPrivateKey privateKey) {
205-
var version = ASN1Integer(BigInt.from(0));
206-
207-
var algorithmSeq = new ASN1Sequence();
208-
var algorithmAsn1Obj = new ASN1Object.fromBytes(Uint8List.fromList(
209-
[0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1]));
210-
var paramsAsn1Obj =
211-
new ASN1Object.fromBytes(Uint8List.fromList([0x5, 0x0]));
212-
algorithmSeq.add(algorithmAsn1Obj);
213-
algorithmSeq.add(paramsAsn1Obj);
214-
215-
var privateKeySeq = new ASN1Sequence();
216-
var modulus = ASN1Integer(privateKey.n);
217-
var publicExponent = ASN1Integer(BigInt.parse('65537'));
218-
var privateExponent = ASN1Integer(privateKey.d);
219-
var p = ASN1Integer(privateKey.p);
220-
var q = ASN1Integer(privateKey.q);
221-
var dP = privateKey.d % (privateKey.p - BigInt.from(1));
222-
var exp1 = ASN1Integer(dP);
223-
var dQ = privateKey.d % (privateKey.q - BigInt.from(1));
224-
var exp2 = ASN1Integer(dQ);
225-
var iQ = privateKey.q.modInverse(privateKey.p);
226-
var co = ASN1Integer(iQ);
227-
228-
privateKeySeq.add(version);
229-
privateKeySeq.add(modulus);
230-
privateKeySeq.add(publicExponent);
231-
privateKeySeq.add(privateExponent);
232-
privateKeySeq.add(p);
233-
privateKeySeq.add(q);
234-
privateKeySeq.add(exp1);
235-
privateKeySeq.add(exp2);
236-
privateKeySeq.add(co);
237-
var publicKeySeqOctetString =
238-
new ASN1OctetString(Uint8List.fromList(privateKeySeq.encodedBytes));
239-
240-
var topLevelSeq = new ASN1Sequence();
241-
topLevelSeq.add(version);
242-
topLevelSeq.add(algorithmSeq);
243-
topLevelSeq.add(publicKeySeqOctetString);
244-
var dataBase64 = base64.encode(topLevelSeq.encodedBytes);
245-
246-
return """-----BEGIN PRIVATE KEY-----\r\n$dataBase64\r\n-----END PRIVATE KEY-----""";
247-
}
248-
249-
/// Encode Public key to PEM Format
250-
///
251-
/// Given [RSAPublicKey] returns a base64 encoded [String] with standard PEM headers and footers
252-
String encodePublicKeyToPemPKCS8(RSAPublicKey publicKey) {
253-
var algorithmSeq = new ASN1Sequence();
254-
var algorithmAsn1Obj = new ASN1Object.fromBytes(Uint8List.fromList(
255-
[0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1]));
256-
var paramsAsn1Obj =
257-
new ASN1Object.fromBytes(Uint8List.fromList([0x5, 0x0]));
258-
algorithmSeq.add(algorithmAsn1Obj);
259-
algorithmSeq.add(paramsAsn1Obj);
260-
261-
var publicKeySeq = new ASN1Sequence();
262-
publicKeySeq.add(ASN1Integer(publicKey.modulus));
263-
publicKeySeq.add(ASN1Integer(publicKey.exponent));
264-
var publicKeySeqBitString =
265-
new ASN1BitString(Uint8List.fromList(publicKeySeq.encodedBytes));
266-
267-
var topLevelSeq = new ASN1Sequence();
268-
topLevelSeq.add(algorithmSeq);
269-
topLevelSeq.add(publicKeySeqBitString);
270-
var dataBase64 = base64.encode(topLevelSeq.encodedBytes);
271-
return """-----BEGIN PUBLIC KEY-----\r\n$dataBase64\r\n-----END PUBLIC KEY-----""";
272-
}
273-
274218
/// Encode Public key to PEM Format
275219
///
276220
/// Given [RSAPublicKey] returns a base64 encoded [String] with standard PEM headers and footers
@@ -289,9 +233,9 @@ class RsaKeyHelper {
289233
///
290234
/// Returns a [AsymmetricKeyPair] based on the [RSAKeyGenerator] with custom parameters,
291235
/// including a [SecureRandom]
292-
AsymmetricKeyPair<PublicKey, PrivateKey> computeRSAKeyPair(
236+
AsymmetricKeyPair<PublicKey, PrivateKey> getRsaKeyPair(
293237
SecureRandom secureRandom) {
294-
var rsapars = new RSAKeyGeneratorParameters(BigInt.from(65537), 2048, 12);
238+
var rsapars = new RSAKeyGeneratorParameters(BigInt.from(65537), 2048, 5);
295239
var params = new ParametersWithRandom(rsapars, secureRandom);
296240
var keyGenerator = new RSAKeyGenerator();
297241
keyGenerator.init(params);

pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ packages:
106106
name: source_span
107107
url: "https://pub.dartlang.org"
108108
source: hosted
109-
version: "1.5.3"
109+
version: "1.5.4"
110110
stack_trace:
111111
dependency: transitive
112112
description:

test/widget_test.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77

88
import 'package:flutter/material.dart';
99
import 'package:flutter_test/flutter_test.dart';
10+
import 'package:pointycastle/key_generators/rsa_key_generator.dart';
11+
import 'package:pointycastle/pointycastle.dart';
1012

1113
import 'package:rsa_key_generator/main.dart';
14+
import 'package:rsa_key_generator/utils/rsa_key_helper.dart';
1215

1316
void main() {
1417
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
@@ -27,4 +30,18 @@ void main() {
2730
expect(find.text('0'), findsNothing);
2831
expect(find.text('1'), findsOneWidget);
2932
});
33+
34+
test("test", () async {
35+
RsaKeyHelper helper = RsaKeyHelper();
36+
var keyPair = await helper.computeRSAKeyPair(helper.getSecureRandom());
37+
print(keyPair.privateKey.toString());
38+
});
39+
40+
test("Keys test", () {
41+
var keyGenerator = new RSAKeyGenerator();
42+
var keypair = keyGenerator.generateKeyPair();
43+
expect(keypair, isNotNull);
44+
});
3045
}
46+
47+

0 commit comments

Comments
 (0)