Add RSA keys generation

This commit is contained in:
Hugo Pointcheval 2021-05-08 20:11:28 +02:00
parent 36e942f41e
commit 871e3b74ed
4 changed files with 65 additions and 4 deletions

View File

@ -7,6 +7,7 @@
// Author: Hugo Pointcheval // Author: Hugo Pointcheval
// //
import Foundation import Foundation
import CommonCrypto
class KeyGeneration { class KeyGeneration {
func keygen(size : NSNumber) -> Data? { func keygen(size : NSNumber) -> Data? {
@ -22,4 +23,37 @@ class KeyGeneration {
} }
return nil return nil
} }
@available(iOS 10.0, watchOS 3.0, tvOS 10.0, *)
func rsaKeypairGen(size : NSNumber) throws -> [Data]? {
let tagData = UUID().uuidString.data(using: .utf8)
let isPermanent = true
let attributes: [CFString: Any] = [
kSecAttrKeyType: kSecAttrKeyTypeRSA,
kSecAttrKeySizeInBits: (size.intValue * 8),
kSecPrivateKeyAttrs: [
kSecAttrIsPermanent: isPermanent,
kSecAttrApplicationTag: tagData!
]
]
var error: Unmanaged<CFError>?
guard let privKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
throw error!.takeRetainedValue() as Error
}
let pubKey = SecKeyCopyPublicKey(privKey)
var errorExport: Unmanaged<CFError>?
let data1 = SecKeyCopyExternalRepresentation(pubKey!, &errorExport)
let unwrappedData1 = data1 as Data?
let data2 = SecKeyCopyExternalRepresentation(privKey, &errorExport)
let unwrappedData2 = data2 as Data?
return [unwrappedData1!, unwrappedData2!]
}
} }

View File

@ -79,6 +79,31 @@ public class SwiftNativeCryptoPlugin: NSObject, FlutterPlugin {
message: "GENERATED KEY IS NIL.", message: "GENERATED KEY IS NIL.",
details: nil)) details: nil))
} }
case "rsaKeypairGen":
let args = call.arguments as! NSDictionary
let size = args["size"] as! NSNumber
let keypair : [Data]?
if #available(iOS 10.0, *) {
do {
keypair = try KeyGeneration().rsaKeypairGen(size: size)
} catch {
keypair = nil
}
} else {
// Fallback on earlier versions
keypair = nil
}
if keypair != nil {
result(keypair)
} else {
result(FlutterError(code: "KEYPAIRGENERROR",
message: "GENERATED KEYPAIR IS EMPTY.",
details: nil))
}
case "encrypt": case "encrypt":
let args = call.arguments as! NSDictionary let args = call.arguments as! NSDictionary

View File

@ -61,7 +61,7 @@ class RSAKeyEncapsulationMechanism implements KeyEncapsulationMechanism {
@override @override
Future<Encapsulation> encapsulate() { Future<Encapsulation> encapsulate() {
if (!_isInit) { if (!_isInit || _mode == KemMode.DECAPSULATION) {
throw KemInitException("KEM not properly initialized."); throw KemInitException("KEM not properly initialized.");
} }
throw UnimplementedError(); throw UnimplementedError();
@ -69,6 +69,9 @@ class RSAKeyEncapsulationMechanism implements KeyEncapsulationMechanism {
@override @override
Future<SecretKey> decapsulate(Encapsulation encapsulation) { Future<SecretKey> decapsulate(Encapsulation encapsulation) {
if (!_isInit || _mode == KemMode.ENCAPSULATION) {
throw KemInitException("KEM not properly initialized.");
}
throw UnimplementedError(); throw UnimplementedError();
} }
} }

View File

@ -99,7 +99,7 @@ class Platform {
Future<List<Uint8List>> rsaKeypairGen(int size) async { Future<List<Uint8List>> rsaKeypairGen(int size) async {
try { try {
final List<Uint8List> keypair = final List<Uint8List> keypair =
await call('rsaKeypairGen', <String, dynamic>{ await callList('rsaKeypairGen', <String, dynamic>{
'size': size, 'size': size,
}); });
return keypair; return keypair;
@ -146,8 +146,7 @@ class Platform {
CipherParameters parameters, CipherParameters parameters,
) async { ) async {
try { try {
final Uint8List data = final Uint8List data = await call('decrypt', <String, dynamic>{
await _channel.invokeMethod('decrypt', <String, dynamic>{
'payload': payload, 'payload': payload,
'key': key, 'key': key,
'algorithm': algorithm.name, 'algorithm': algorithm.name,