Assine, verifique, criptografar e descriptografar usando o enclave seguro no iOS e macOS.
Suporta o código de passagem do FaceID, TouchID, e a senha do aplicativo.
O uso da estrutura de segurança pode ser um pouco confuso. É por isso que eu criei isso. Você pode usá -lo como código e orientação de exemplo ou pode usá -lo como uma micro -estrutura.
Achei complicado descobrir como usar o SecKeyRawVerify , SecKeyGeneratePair e SecItemCopyMatching C APIs no Swift 3, mas a implementação é bastante direta, graças aos impressionantes recursos rápidos.
Basta arrastar Sources/EllipticCurveKeyPair.swift e Sources/SHA256.swift Arquivo no seu projeto Xcode.
pod EllipticCurveKeyPair github "agens-no/EllipticCurveKeyPair" Existem muitas grandes possibilidades com o Enclave Seguro. Aqui estão alguns exemplos
Disponível apenas no iOS 10 e acima
Um caso de uso pode ser
Para mais exemplos, consulte o aplicativo de demonstração.
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 )
} ( )
}Você também pode graciosamente sobre o uso do chaveiro se o Secure Enclave não estiver disponível usando diferentes sinalizadores de controle de acesso:
let privateAccessControl = EllipticCurveKeyPair . AccessControl ( protection : kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly , flags : {
return EllipticCurveKeyPair . Device . hasSecureEnclave ? [ . userPresence , . privateKeyUsage ] : [ . userPresence ]
} ( ) ) Nesse caso, você precisa se lembrar de definir a variável token no objeto Config para .secureEnclaveIfAvailable .
do {
let key = try KeyPair . manager . publicKey ( ) . data ( ) . DER // Data
} catch {
// handle error
}Veja o aplicativo de demonstração para o exemplo de trabalho
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
}Você também pode passar por um objeto Lacontext ao assinar
do {
let digest = " some text to encrypt " . data ( using : . utf8 ) !
let encrypted = try KeyPair . manager . encrypt ( digest , hash : . sha256 )
} catch {
// handle error
}Você também pode criptografar em um dispositivo/OS/plataforma diferente usando a chave pública. Se você quiser saber todos os detalhes sobre como criptografar em um formato que o Enclave Seguro entende, então você precisa definitivamente ler esta ótima gravação por @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
}Você também pode passar por um objeto Lacontext ao descriptografar
O mais comum é capturar erros relacionados a
Com 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 ) " )
} Com 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 ) " )
} Para inspecionar as consultas que estão indo e voltando para o chaveiro, você pode imprimir para consolar todas as mutações que esta biblioteca faz no chaveiro assim
EllipticCurveKeyPair . logger = { print ( $0 ) } No aplicativo de demonstração, você verá que cada vez que criar uma assinatura, algumas informações úteis são registradas no console.
Exemplo de saída
#! /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.datPara executar este script, você pode
verify.shchmod u+x verify.sh./verify.shEntão você deve ver
Verified OKPS: Este script criará 4 arquivos no seu diretório atual.
Estrutura de segurança, Swift 3, Swift 4, Swift, SeckeyRawVerify, SeckeyGeReRairPair, Secitemcopymatching, Secp256R1, Cryptografia da Curva Elíptica, EcdSa, Ecdh, ASN.1, Apple, IOS, Mac Os, KsecTkeyTkeyPeecSeRandomom, KSECATTRTOKENIDSECUREENCLAVE, LACONTEXT, LOCALATHENTICATION, FACEID, FACE ID, TouchId, Touch ID, senha do aplicativo, pino de dispositivo, dispositivo de dispositivo
Trailfbits publicou algum código Objective-C há algum tempo, o que estava em grande ajuda! Obrigado por compartilhar Tidas e SecureEnclaveCrypto. Eles também receberam outros projetos mais interessantes. Confira!
Ele compartilhou algumas idéias muito valiosas em relação à exportação da chave pública no formato Der X.509 adequado.
A classe SHA256 (originalmente SHA2.swift ) é encontrada na inestimável biblioteca criptográfica de Marcin Krzyżanowski. A classe foi fortemente alterada para retirá -la ao mínimo para o que precisávamos neste projeto.
Por que não estou sendo solicitado com o Touch ID / Disposity Pin no simulador?
O simulador não possui nenhum enclave seguro e, portanto, tentar acessá -lo apenas levaria a erros. Se você definir
fallbackToKeychainIfSecureEnclaveIsNotAvailablenão está disponível paratrue, a chave privada será armazenada no Keychain no simulador, facilitando o teste do seu aplicativo no simulador.
Onde posso aprender mais?
Confira este vídeo no WWDC 2015 sobre segurança em geral ou clique aqui para pular a seção sobre o Enclave seguro.
Por que está envolvido em uma enumeração?
Eu tento equilibrar a arrastar e soltar os arquivos necessários para o Xcode e suportar gerentes de dependência como Cartago e Cocoapods ao mesmo tempo. Se você tem idéias melhores ou não concorda com esta decisão, fico feliz em discutir alternativas :)
Nós faríamos? para ouvir sua opinião sobre esta biblioteca. Se você gosta ou não. Por favor, arquive um problema se houver algo que você gostaria de ver melhorado. Você pode me alcançar como @Hfossli no Twitter e em outros lugares. ?