Signez, vérifiez, cryptant et décryptez à l'aide de l'enclave sécurisé sur iOS et MacOS.
Prend en charge FACEID, TOUCHID, le code de réussite de l'appareil et le mot de passe de l'application.
L'utilisation du cadre de sécurité peut être un peu déroutant. C'est pourquoi j'ai créé cela. Vous pouvez l'utiliser comme exemple de code et de conseils ou vous pouvez l'utiliser comme micro-framework.
J'ai trouvé difficile de comprendre comment utiliser les API C SecKeyRawVerify , SecKeyGeneratePair et SecItemCopyMatching dans Swift 3, mais l'implémentation est assez simple grâce à de superbes fonctionnalités Swift.
Faites simplement glisser Sources/EllipticCurveKeyPair.swift et Sources/SHA256.swift dans votre projet Xcode.
pod EllipticCurveKeyPair github "agens-no/EllipticCurveKeyPair" Il y a beaucoup de grandes possibilités avec une enclave sécurisée. Voici quelques exemples
Uniquement disponible sur iOS 10 et plus
Un cas d'utilisation pourrait être
Pour plus d'exemples, voir l'application de démonstration.
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 )
} ( )
}Vous pouvez également se rendre gracieusement en train d'utiliser le trousseau si Secred Enclave n'est pas disponible en utilisant différents indicateurs de contrôle d'accès:
let privateAccessControl = EllipticCurveKeyPair . AccessControl ( protection : kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly , flags : {
return EllipticCurveKeyPair . Device . hasSecureEnclave ? [ . userPresence , . privateKeyUsage ] : [ . userPresence ]
} ( ) ) Dans ce cas, vous devez vous souvenir de définir la variable token dans Config Object to .secureEnclaveIfAvailable .
do {
let key = try KeyPair . manager . publicKey ( ) . data ( ) . DER // Data
} catch {
// handle error
}Voir l'application de démonstration pour l'exemple de travail
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
}Vous pouvez également passer un objet LaconText lors de la signature
do {
let digest = " some text to encrypt " . data ( using : . utf8 ) !
let encrypted = try KeyPair . manager . encrypt ( digest , hash : . sha256 )
} catch {
// handle error
}Vous pouvez également crypter sur un autre appareil / système d'exploitation / plate-forme en utilisant la clé publique. Si vous voulez connaître tous les détails sur la façon de crypter dans un format que l'Enclave sécurisée comprend, alors vous devez certainement lire cette excellente rédaction par @dschuetz!
https://darthnull.org/security/2018/05/31/secure-enclave-ecies/
do {
let encrypted = ...
let decrypted = try KeyPair . manager . decrypt ( encrypted , hash : . sha256 )
let decryptedString = String ( data : decrypted , encoding : . utf8 )
} catch {
// handle error
}Vous pouvez également passer un objet Lacontext lors du décryptage
La chose la plus courante est d'attraper une erreur liée à
Avec 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 ) " )
} Avec 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 ) " )
} Afin d'inspecter les requêtes en train de faire des allers
EllipticCurveKeyPair . logger = { print ( $0 ) } Dans l'application de démonstration, vous verrez que chaque fois que vous créez une signature, des informations utiles sont enregistrées sur Console.
Exemple de sortie
#! /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.datAfin d'exécuter ce script, vous pouvez
verify.shchmod u+x verify.sh./verify.shAlors tu devrais voir
Verified OKPS: Ce script créera 4 fichiers dans votre répertoire actuel.
Sécurité Framework, Swift 3, Swift 4, Swift, SeckeyRaWverify, SeckeyGereateRepAir, SecitemCopymatching, SECP256R1, Elliptic Curve Cryptography, ECDSA, ECDH, ASN.1, Apple, IOS, Mac OS, KSECATTRYTYPECEC ksecattrtokenidsecureenclave, lacontext, autauthentification locale, faceid, id de face, touched, id tactile, mot de passe d'application, broche de périphérique, périphérique
TrailofBits a publié un code objectif-C il y a quelque temps, ce qui était d'une grande aide! Merci d'avoir partagé Tidas et Securenclavecrypto. Ils ont également obtenu d'autres projets les plus intéressants. Vérifiez-les!
Il a partagé des informations très précieuses en ce qui concerne l'exportation de la clé publique dans le format Der X.509 approprié.
La classe SHA256 (à l'origine SHA2.swift ) se trouve dans la bibliothèque Inestimable Cryptoswift de Marcin Krzyżanowski. La classe a été fortement modifiée afin de le dépasser au strict minimum pour ce dont nous avions besoin dans ce projet.
Pourquoi ne suis-je pas invité avec la broche tactile ID / périphérique sur le simulateur?
Le simulateur ne possède pas d'enclave sécurisé et donc essayer d'y accéder entraînerait simplement des erreurs. Si vous définissez
fallbackToKeychainIfSecureEnclaveIsNotAvailableàtrue, la clé privée sera stockée dans Keychain sur Simulator, ce qui facilite également le test de votre application sur Simulator.
Où puis-je en savoir plus?
Consultez cette vidéo sur WWDC 2015 sur la sécurité en général ou cliquez ici pour passer à la section sur l'enclave sécurisée.
Pourquoi est-il enveloppé dans une enum?
J'essaie d'équilibrer le glisser-déposer les fichiers dont vous avez besoin dans Xcode et de prendre en charge les gestionnaires de dépendances comme Carthage et Cocoapods en même temps. Si vous avez de meilleures idées ou si vous n'êtes pas d'accord avec cette décision, je suis heureux de discuter des alternatives :)
Nous le ferions? Pour entendre votre opinion sur cette bibliothèque. Si vous aimez ou pas. Veuillez déposer un problème s'il y a quelque chose que vous aimeriez voir amélioré. Vous pouvez me joindre en tant que @hfossli sur Twitter et ailleurs. ?