124 lines
4.3 KiB
Dart
124 lines
4.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:pointycastle/export.dart' as crypto;
|
|
import 'dart:math';
|
|
import 'dart:convert';
|
|
import 'dart:typed_data';
|
|
import 'package:asn1lib/asn1lib.dart';
|
|
|
|
class GenerationNouvellePaireClesPage extends StatelessWidget {
|
|
const GenerationNouvellePaireClesPage({super.key});
|
|
|
|
Future<Map<String, String>> _generateKeyPair() async {
|
|
// key generation logic using pointycastle
|
|
final keyParams = crypto.RSAKeyGeneratorParameters(
|
|
BigInt.parse('65537'),
|
|
2048,
|
|
64,
|
|
);
|
|
|
|
final secureRandom = crypto.FortunaRandom();
|
|
|
|
// Seed the random number generator
|
|
final random = Random.secure();
|
|
final seeds = List<int>.generate(32, (_) => random.nextInt(256));
|
|
secureRandom.seed(crypto.KeyParameter(Uint8List.fromList(seeds)));
|
|
|
|
final rngParams = crypto.ParametersWithRandom(keyParams, secureRandom);
|
|
final keyGenerator = crypto.RSAKeyGenerator();
|
|
keyGenerator.init(rngParams);
|
|
|
|
final pair = keyGenerator.generateKeyPair();
|
|
final publicKey = pair.publicKey as crypto.RSAPublicKey;
|
|
final privateKey = pair.privateKey as crypto.RSAPrivateKey;
|
|
|
|
// Convert keys to PEM format
|
|
final publicKeyPem = _encodePublicKeyToPemPKCS1(publicKey);
|
|
final privateKeyPem = _encodePrivateKeyToPemPKCS1(privateKey);
|
|
|
|
// Save keys securely (not implemented here)
|
|
|
|
return {'publicKey': publicKeyPem, 'privateKey': privateKeyPem};
|
|
}
|
|
|
|
String _encodePublicKeyToPemPKCS1(crypto.RSAPublicKey publicKey) {
|
|
final bytes = _encodePublicKeyToDer(publicKey);
|
|
return _formatPem(bytes, 'RSA PUBLIC KEY');
|
|
}
|
|
|
|
String _encodePrivateKeyToPemPKCS1(crypto.RSAPrivateKey privateKey) {
|
|
final bytes = _encodePrivateKeyToDer(privateKey);
|
|
return _formatPem(bytes, 'RSA PRIVATE KEY');
|
|
}
|
|
|
|
Uint8List _encodePublicKeyToDer(crypto.RSAPublicKey publicKey) {
|
|
final algorithmSeq = ASN1Sequence();
|
|
algorithmSeq.add(ASN1ObjectIdentifier.fromName('rsaEncryption'));
|
|
algorithmSeq.add(ASN1Null());
|
|
|
|
final publicKeySeq = ASN1Sequence();
|
|
publicKeySeq.add(ASN1Integer(publicKey.modulus!));
|
|
publicKeySeq.add(ASN1Integer(publicKey.exponent!));
|
|
|
|
final publicKeyBitString = ASN1BitString(Uint8List.fromList(publicKeySeq.encodedBytes));
|
|
|
|
final topLevelSeq = ASN1Sequence();
|
|
topLevelSeq.add(algorithmSeq);
|
|
topLevelSeq.add(publicKeyBitString);
|
|
|
|
return Uint8List.fromList(topLevelSeq.encodedBytes);
|
|
}
|
|
|
|
Uint8List _encodePrivateKeyToDer(crypto.RSAPrivateKey privateKey) {
|
|
final privateKeySeq = ASN1Sequence();
|
|
privateKeySeq.add(ASN1Integer(BigInt.from(0))); // Version
|
|
privateKeySeq.add(ASN1Integer(privateKey.n!));
|
|
privateKeySeq.add(ASN1Integer(privateKey.exponent!));
|
|
privateKeySeq.add(ASN1Integer(privateKey.d!));
|
|
privateKeySeq.add(ASN1Integer(privateKey.p!));
|
|
privateKeySeq.add(ASN1Integer(privateKey.q!));
|
|
privateKeySeq.add(ASN1Integer(privateKey.d! % (privateKey.p! - BigInt.one)));
|
|
privateKeySeq.add(ASN1Integer(privateKey.d! % (privateKey.q! - BigInt.one)));
|
|
privateKeySeq.add(ASN1Integer(privateKey.q!.modInverse(privateKey.p!)));
|
|
|
|
return Uint8List.fromList(privateKeySeq.encodedBytes);
|
|
}
|
|
|
|
String _formatPem(Uint8List bytes, String label) {
|
|
final base64 = base64Encode(bytes);
|
|
final chunks = RegExp('.{1,64}').allMatches(base64).map((m) => m.group(0)!);
|
|
return '-----BEGIN $label-----\n${chunks.join('\n')}\n-----END $label-----';
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Colors.black,
|
|
appBar: AppBar(
|
|
title: const Text('Génération d\'une Nouvelle Paire de Clés'),
|
|
),
|
|
body: Center(
|
|
child: ElevatedButton(
|
|
onPressed: () async {
|
|
final keys = await _generateKeyPair();
|
|
// Display a confirmation dialog or message
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Clés Générées'),
|
|
content: const Text('La nouvelle paire de clés a été générée avec succès.'),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.pop(context),
|
|
child: const Text('OK'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
child: const Text('Générer une Nouvelle Paire de Clés'),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|