Unterschreiben, überprüfen, verschlüsseln und mit der sicheren Enklave auf iOS und macOS entschlüsseln.
Unterstützt FaceID, TouchID, Geräte -Pass -Code und Anwendungskennwort.
Die Verwendung des Sicherheitsrahmens kann etwas verwirrend sein. Deshalb habe ich das geschaffen. Sie können es als Beispielcode und Anleitung verwenden oder als Micro -Framework verwenden.
Ich fand es schwierig, herauszufinden, wie man die SecKeyRawVerify , SecKeyGeneratePair und SecItemCopyMatching C APIs in Swift 3 verwendet, aber die Implementierung ist dank fantastischer Swift -Funktionen durchaus einfach.
Ziehen Sie einfach Sources/EllipticCurveKeyPair.swift und Sources/SHA256.swift -Datei in Ihr Xcode -Projekt.
pod EllipticCurveKeyPair github "agens-no/EllipticCurveKeyPair" Es gibt viele großartige Möglichkeiten mit sicherer Enklave. Hier sind einige Beispiele
Nur auf iOS 10 und höher erhältlich
Ein Anwendungsfall könnte sein
Weitere Beispiele finden Sie in der Demo -App.
struct KeyPair {
static let manager : EllipticCurveKeyPair . Manager = {
let publicAccessControl = EllipticCurveKeyPair . AccessControl ( protection : kSecAttrAccessibleAlwaysThisDeviceOnly , flags : [ ] )
let privateAccessControl = EllipticCurveKeyPair . AccessControl ( protection : kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly , flags : [ . userPresence , . privateKeyUsage ] )
let config = EllipticCurveKeyPair . Config (
publicLabel : " payment.sign.public " ,
privateLabel : " payment.sign.private " ,
operationPrompt : " Confirm payment " ,
publicKeyAccessControl : publicAccessControl ,
privateKeyAccessControl : privateAccessControl ,
token : . secureEnclave )
return EllipticCurveKeyPair . Manager ( config : config )
} ( )
}Sie können auch anmutig zurückfallen, um Schlüsselback zu verwenden, wenn sichere Enklave nicht mit verschiedenen Access Control Flags verfügbar sind:
let privateAccessControl = EllipticCurveKeyPair . AccessControl ( protection : kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly , flags : {
return EllipticCurveKeyPair . Device . hasSecureEnclave ? [ . userPresence , . privateKeyUsage ] : [ . userPresence ]
} ( ) ) In diesem Fall müssen Sie sich daran erinnern, token -Variable im Config auf .secureEnclaveIfAvailable festzulegen.
do {
let key = try KeyPair . manager . publicKey ( ) . data ( ) . DER // Data
} catch {
// handle error
}Siehe Demo -App für Arbeitsbeispiel
do {
let key = try KeyPair . manager . publicKey ( ) . data ( ) . PEM // String
} catch {
// handle error
} do {
let digest = " some text to sign " . data ( using : . utf8 ) !
let signature = try KeyPair . manager . sign ( digest , hash : . sha256 )
} catch {
// handle error
}Sie können bei der Unterschrift auch ein Lacontext -Objekt übergeben
do {
let digest = " some text to encrypt " . data ( using : . utf8 ) !
let encrypted = try KeyPair . manager . encrypt ( digest , hash : . sha256 )
} catch {
// handle error
}Sie können auch auf einem anderen Gerät/Betriebssystem/einer anderen Plattform mit dem öffentlichen Schlüssel verschlüsseln. Wenn Sie alle Details darüber wissen möchten, wie die sichere Enklave in einem Format verschlüsselt werden, müssen Sie dieses großartige Schreiben von @dschuetz auf jeden Fall lesen!
https://darthnull.org/security/2018/05/31/secure-clave-ecies/
do {
let encrypted = ...
let decrypted = try KeyPair . manager . decrypt ( encrypted , hash : . sha256 )
let decryptedString = String ( data : decrypted , encoding : . utf8 )
} catch {
// handle error
}Sie können beim Entschlüsseln auch ein Lacontext -Objekt übergeben
Das häufigste ist, einen Fehler in Verbindung zu fangen
Mit do/catch :
do {
let decrypted = try KeyPair . manager . decrypt ( encrypted )
} catch EllipticCurveKeyPair . Error . underlying ( _ , let underlying ) where underlying . code == errSecUnimplemented {
print ( " Unsupported device " )
} catch EllipticCurveKeyPair . Error . authentication ( let authenticationError ) where authenticationError . code == . userCancel {
print ( " User cancelled/dismissed authentication dialog " )
} catch {
print ( " Some other error occurred. Error ( error ) " )
} Mit if let :
if case let EllipticCurveKeyPair . Error . underlying ( _ , underlying ) = error , underlying . code == errSecUnimplemented {
print ( " Unsupported device " )
} else if case let EllipticCurveKeyPair . Error . authentication ( authenticationError ) , authenticationError . code == . userCancel {
print ( " User cancelled/dismissed authentication dialog " )
} else {
print ( " Some other error occurred. Error ( error ) " )
} Um die Abfragen zu überprüfen,
EllipticCurveKeyPair . logger = { print ( $0 ) } In der Demo -App sehen Sie, dass jedes Mal, wenn Sie eine Unterschrift erstellen, einige nützliche Informationen an der Konsole angemeldet sind.
Beispielausgabe
#! /bin/sh
echo 414243 | xxd -r -p > dataToSign.dat
echo 3046022100842512baa16a3ec9b977d4456923319442342e3fdae54f2456af0b7b8a09786b022100a1b8d762b6cb3d85b16f6b07d06d2815cb0663e067e0b2f9a9c9293bde8953bb | xxd -r -p > signature.dat
cat > key.pem << EOF
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdDONNkwaP8OhqFTmjLxVcByyPa19
ifY2IVDinFei3SvCBv8fgY8AU+Fm5oODksseV0sd4Zy/biSf6AMr0HqHcw==
-----END PUBLIC KEY-----
EOF
/usr/local/opt/openssl/bin/openssl dgst -sha256 -verify key.pem -signature signature.dat dataToSign.datUm dieses Skript auszuführen, können Sie
verify.shchmod u+x verify.sh./verify.shDann solltest du sehen
Verified OKPS: Dieses Skript erstellt 4 Dateien in Ihrem aktuellen Verzeichnis.
Security framework, Swift 3, Swift 4, Swift, SecKeyRawVerify, SecKeyGeneratePair, SecItemCopyMatching, secp256r1, Elliptic Curve Cryptography, ECDSA, ECDH, ASN.1, Apple, iOS, Mac OS, kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyTypeEC, KSECATTRTOKEIDSECURECLAVE, LACONTEXT, LOCALAUTHENTIKATION, FACEID, FACE ID, TouchID, Touch -ID, Anwendungskennwort, Geräte -Pin, Gerätepin
Trailofbits veröffentlichte vor einiger Zeit einen objektiven Code, der große Hilfe war! Vielen Dank, dass Sie Tidas und SecureClaveCrypto geteilt haben. Sie haben auch einige andere interessanteste Projekte. Schau sie dir an!
Er teilte einige sehr wertvolle Erkenntnisse in Bezug auf den Export des öffentlichen Schlüssels im ordnungsgemäßen Der x.509 -Format.
Die SHA256 -Klasse (ursprünglich SHA2.swift ) befindet sich in der unschätzbaren Cryptoswift -Bibliothek von Marcin Krzyżanowski. Die Klasse wurde stark verändert, um sie für das, was wir in diesem Projekt brauchten, auf ihr Minimum zu ziehen.
Warum werde ich nicht mit Touch ID / Geräte -Pin am Simulator aufgefordert?
Der Simulator besitzt keine sichere Enklave und versucht daher, darauf zuzugreifen, nur zu Fehlern. Wenn Sie
fallbackToKeychainIfSecureEnclaveIsNotAvailableauftrueeinstellen, wird der private Schlüssel in Keychain auf Simulator gespeichert, um Ihre Anwendung auch auf Simulator zu testen.
Wo kann ich mehr lernen?
Schauen Sie sich dieses Video unter der WWDC 2015 über die Sicherheit im Allgemeinen an oder klicken Sie hier, um direkt zum Abschnitt zur sicheren Enklave zu überspringen.
Warum ist es in eine Aufzählung eingewickelt?
Ich versuche, die Dateien, die Sie benötigen, in Xcode und die Unterstützung von Abhängigkeitsmanagern wie Karthago und Cocoapods gleichzeitig zu Balance, die Dateien auszugleichen. Wenn Sie bessere Ideen haben oder dieser Entscheidung nicht zustimmen, diskutiere ich gerne Alternativen :)
Wir würden? um Ihre Meinung zu dieser Bibliothek zu hören. Was magst du oder nicht. Bitte stellen Sie ein Problem ein, wenn Sie etwas verbessern möchten. Sie können mich auf Twitter und anderswo als @hfossli erreichen. ?