使用iOS和MACOS上的安全飛地簽名,驗證,加密和解密。
支持faceID,TouchID,設備通過代碼和應用程序密碼。
使用安全框架可能會有些混亂。這就是為什麼我創建這個。您可以將其用作示例代碼和指導,也可以將其用作微框架。
我發現很難弄清楚如何使用Swift 3中的SecKeyRawVerify , SecKeyGeneratePair和SecItemCopyMatching c apis,但是由於出色的Swift功能,實現非常直接。
只需將Sources/EllipticCurveKeyPair.swift和Sources/SHA256.swift拖放到您的Xcode Project中即可。
pod EllipticCurveKeyPair github "agens-no/EllipticCurveKeyPair" 安全飛地有很多很大的可能性。這裡有一些例子
僅在iOS 10及以上可用
用例可能是
有關更多示例,請參見演示應用。
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 )
} ( )
}如果使用不同的訪問控制標誌,則您也可以優雅地退縮以使用鑰匙串:
let privateAccessControl = EllipticCurveKeyPair . AccessControl ( protection : kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly , flags : {
return EllipticCurveKeyPair . Device . hasSecureEnclave ? [ . userPresence , . privateKeyUsage ] : [ . userPresence ]
} ( ) )在這種情況下,您需要記住將Config Object中的token變量設置為.secureEnclaveIfAvailable 。
do {
let key = try KeyPair . manager . publicKey ( ) . data ( ) . DER // Data
} catch {
// handle error
}有關工作示例,請參見演示應用
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
}簽名時,您也可以通過lactext對象
do {
let digest = " some text to encrypt " . data ( using : . utf8 ) !
let encrypted = try KeyPair . manager . encrypt ( digest , hash : . sha256 )
} catch {
// handle error
}您也可以使用公共密鑰在其他設備/OS/平台上加密。如果您想了解有關如何以Secure Enclave理解的格式加密的所有詳細信息,那麼您絕對需要閱讀@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
}解密時您也可以通過lactext對象
最常見的事情是捕獲與
與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 ) " )
} 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 ) " )
} 為了檢查來迴向鍵鏈來回查詢,您可以打印以安裝該庫在這樣的鑰匙串上執行的每個突變
EllipticCurveKeyPair . logger = { print ( $0 ) } 在演示應用程序中,您會看到每次創建簽名時,都會記錄一些有用的信息到控制台。
示例輸出
#! /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.dat為了運行此腳本,您可以
verify.shchmod u+x verify.sh./verify.sh那你應該看到
Verified OKPS:此腳本將在您當前目錄中創建4個文件。
Security framework, Swift 3, Swift 4, Swift, SecKeyRawVerify, SecKeyGeneratePair, SecItemCopyMatching, secp256r1, Elliptic Curve Cryptography, ECDSA, ECDH, ASN.1, Apple, iOS, Mac OS, kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyTypeEC, kSecAttrTokenIDSecureEnclave, lactext,localauthentication,faceid,face id,touchID,觸摸ID,應用程序密碼,設備PIN,DEVICEPIN
TrailofBits不久前發布了一些Objective-C代碼,這對您有很大的幫助!感謝您分享Tidas和SecureenclaveCrypto。他們還收到了其他一些最有趣的項目。檢查一下!
他分享了SOM非常有價值的見解,以適當的der X.509格式出口公共密鑰。
SHA256類(最初是SHA2.swift )是在MarcinKrzyżanowski的寶貴隱式庫中找到的。為了將其劃分至最低限度,該課程已進行了大量更改。
為什麼在模擬器上沒有提示我使用觸摸ID /設備引腳的提示?
模擬器沒有任何安全的飛地,因此試圖訪問它只會導致錯誤。如果將
fallbackToKeychainIfSecureEnclaveIsNotAvailable設置為true,則將私鑰存儲在模擬器上的鍵鏈中,從而可以易於測試您在模擬器上的應用程序。
我在哪裡可以學到更多?
在WWDC 2015上查看有關安全性的視頻,或單擊此處跳過有關安全飛地的部分。
為什麼它包裹在枚舉中?
我嘗試在XCode中平衡所需的拖放文件,並同時支持迦太基和Cocoapods等依賴性經理。如果您有更好的想法或不同意這個決定,我很樂意討論替代方案:)
我們會嗎?聆聽您對此圖書館的看法。您喜歡還是不喜歡。如果您想改進一些問題,請提出問題。您可以在Twitter和其他地方作為@hfossli與我聯繫。 ?