ลงชื่อตรวจสอบเข้ารหัสและถอดรหัสโดยใช้ Enclave ที่ปลอดภัยบน iOS และ MacOS
รองรับ FACEID, TouchID, รหัสผ่านอุปกรณ์และรหัสผ่านแอปพลิเคชัน
การใช้กรอบความปลอดภัยอาจทำให้เกิดความสับสนเล็กน้อย นั่นเป็นเหตุผลที่ฉันสร้างสิ่งนี้ คุณอาจใช้เป็นรหัสตัวอย่างและคำแนะนำหรือคุณอาจใช้เป็นกรอบไมโคร
ฉันพบว่ามันยากที่จะหาวิธีใช้ SecKeyRawVerify , SecKeyGeneratePair และ SecItemCopyMatching C APIs ใน Swift 3 แต่การใช้งานค่อนข้างตรงไปตรงมาขอบคุณคุณสมบัติ Swift ที่ยอดเยี่ยม
เพียงแค่ลาก Sources/EllipticCurveKeyPair.swift และ Sources/SHA256.swift ไฟล์ลงในโครงการ XCode ของคุณ
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 )
} ( )
}นอกจากนี้คุณยังสามารถย้อนกลับอย่างสง่างามในการใช้พวงกุญแจหากไม่มี Enclave ที่ปลอดภัยโดยใช้ธงควบคุมการเข้าถึงที่แตกต่างกัน:
let privateAccessControl = EllipticCurveKeyPair . AccessControl ( protection : kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly , flags : {
return EllipticCurveKeyPair . Device . hasSecureEnclave ? [ . userPresence , . privateKeyUsage ] : [ . userPresence ]
} ( ) ) ในกรณีนี้คุณต้องจำไว้ว่าให้ตั้งค่าตัวแปร token ในวัตถุ Config เป็น .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
}คุณอาจผ่านวัตถุ lacontext เมื่อลงนาม
do {
let digest = " some text to encrypt " . data ( using : . utf8 ) !
let encrypted = try KeyPair . manager . encrypt ( digest , hash : . sha256 )
} catch {
// handle error
}นอกจากนี้คุณยังสามารถเข้ารหัสบนอุปกรณ์/ระบบปฏิบัติการ/แพลตฟอร์มอื่นโดยใช้คีย์สาธารณะ หากคุณต้องการทราบรายละเอียดทั้งหมดเกี่ยวกับวิธีการเข้ารหัสในรูปแบบ 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
}คุณอาจผ่านวัตถุ lacontext เมื่อถอดรหัส
สิ่งที่พบบ่อยที่สุดคือการจับข้อผิดพลาดที่เกี่ยวข้องกับ
ด้วย 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 ไฟล์ในไดเรกทอรีปัจจุบันของคุณ
กรอบความปลอดภัย, Swift 3, Swift 4, Swift, Seckeyrawverify, SeckeyGeneratepair, SecitemCopymatching, Secp256R1, การเข้ารหัสเส้นโค้งรูปไข่, ECDSA, ECDH, ASN.1, Apple, iOS, Mac OS KSECATTRENKELIDSECUREENCLAVE, LACONTETET
Trailofbits เผยแพร่รหัส Objective-C สักพักหนึ่งซึ่งเป็นความช่วยเหลือที่ดี! ขอบคุณสำหรับการแบ่งปัน TIDAS และ SecureEnclavepto พวกเขายังได้รับโครงการที่น่าสนใจที่สุดอื่น ๆ ตรวจสอบพวกเขา!
เขาแบ่งปันข้อมูลเชิงลึกที่มีค่ามากเกี่ยวกับการส่งออกคีย์สาธารณะในรูปแบบ DER X.509 ที่เหมาะสม
คลาส SHA256 (เดิมที SHA2.swift ) พบได้ในห้องสมุด cryptoswift ที่มีค่าโดย Marcin Krzyżanowski ชั้นเรียนได้รับการเปลี่ยนแปลงอย่างมากเพื่อที่จะตัดมันลงไปในขั้นต่ำที่เปลือยเปล่าสำหรับสิ่งที่เราต้องการในโครงการนี้
ทำไมฉันถึงไม่ได้รับการแจ้งเตือนด้วย Touch ID / อุปกรณ์พินบนเครื่องจำลอง?
เครื่องจำลองไม่ได้มีวงล้อมที่ปลอดภัยและพยายามเข้าถึงมันจะนำไปสู่ข้อผิดพลาด หากคุณตั้งค่า
fallbackToKeychainIfSecureEnclaveIsNotAvailableเป็นtrueแล้วคีย์ส่วนตัวจะถูกเก็บไว้ในพวงกุญแจบนเครื่องจำลองทำให้ง่ายต่อการทดสอบแอปพลิเคชันของคุณในการจำลองเช่นกัน
ฉันจะเรียนรู้เพิ่มเติมได้ที่ไหน
ลองดูวิดีโอนี้ใน WWDC 2015 เกี่ยวกับความปลอดภัยโดยทั่วไปหรือคลิกที่นี่เพื่อข้ามไปยังส่วนเกี่ยวกับ Enclave ที่ปลอดภัย
ทำไมมันจึงถูกห่อหุ้มด้วย enum?
ฉันพยายามสร้างสมดุลระหว่างการลากและลดไฟล์ที่คุณต้องการลงใน XCode และรองรับผู้จัดการการพึ่งพาเช่น Carthage และ Cocoapods ในเวลาเดียวกัน หากคุณมีความคิดที่ดีกว่าหรือไม่เห็นด้วยกับการตัดสินใจครั้งนี้ฉันยินดีที่จะพูดคุยทางเลือกอื่น :)
เราจะ? เพื่อรับฟังความคิดเห็นของคุณเกี่ยวกับห้องสมุดนี้ คุณชอบหรือไม่ โปรดยื่นปัญหาหากมีบางสิ่งที่คุณต้องการดูดีขึ้น คุณสามารถติดต่อฉันในฐานะ @hfossli บน Twitter และที่อื่น ๆ -