ios, alamofire5: perlu yang setara dengan curl --key foo.key --cert foo, pem --location --request GET 'https: //bar.baz/foo "
Saya memiliki kunci pribadi selain kunci publik untuk menyematkan sertifikat.
Bagaimana mengotentikasi dengan ke server?
$ file *
foo.der: data
foo.private.der: data
diturunkan dengan openssl from
foo.key: PEM RSA private key
foo.pem: PEM certificate
yang saya butuhkan adalah alamofire yang setara dengan ini:
curl --key foo.key --cert foo.pem --location --request GET 'https: // somhostofmine / v1 / welcome /'
$ curl --key ./client_key.pem --cert ./client.pem --location --request GET 'https: // someurl' "Hello wold!"
bekerja
$ curl --cert ./client.pem --location --request GET 'https: // someurl / v1 / welcome /' curl: (58) tidak dapat menyetel file kunci pribadi: './client.pem' ketik PEM
tidak
Jadi saran untuk menggunakan sertifikat itu sendiri tanpa kunci privat tidak akan berhasil.
Apakah kita berurusan dengan penyematan sertifikat di sini atau mengingat adanya kunci pribadi, ini adalah hal lain yang terjadi di sini ???
Jawaban
Anda dapat membuat ServerTrustManagerpassing sebagai parameter evaluator Anda per nama host. Untuk penggunaan pin kunci publik PublicKeysTrustEvaluatorseperti ini:
let evaluators: [String : ServerTrustEvaluating] = [
"your.host.com": PublicKeysTrustEvaluator(performDefaultValidation: false, validateHost: false)
]
let serverTrustManager = ServerTrustManager(evaluators: evaluators)
Untuk penyematan sertifikat, gunakan PinnedCertificatesTrustEvaluatorseperti ini:
let evaluators: [String : ServerTrustEvaluating] = [
"your.host.com": PinnedCertificatesTrustEvaluator(
acceptSelfSignedCertificates: true,
performDefaultValidation: false,
validateHost: false
)
]
let serverTrustManager = ServerTrustManager(evaluators: evaluators)
Kedua metode tersebut memerlukan sertifikat Anda untuk disertakan dalam bundel Anda sebagai .ceratau .derfile.
Setelah membuat ServerTrustManagerpass Anda ke sebuah Sessioninstance dan gunakan ini untuk permintaan Anda:
let session = Session(serverTrustManager: serverTrustManager)
Jika Anda ingin memiliki logika yang lebih kompleks tentang bagaimana Anda memverifikasi server Anda atau Anda harus menggunakan wildcard di domain Anda, Anda harus membuat subkelas ServerTrustManagerdan mengganti serverTrustEvaluator(forHost:)fungsi:
class MyServerTrustManager: ServerTrustManager {
init() {
super.init(evaluators: [:])
}
override func serverTrustEvaluator(forHost host: String) throws -> ServerTrustEvaluating? {
guard host.hasSuffix(".host.com") else {
return try super.serverTrustEvaluator(forHost: host)
}
return PublicKeysTrustEvaluator(performDefaultValidation: false, validateHost: false)
}
}
- mengemas kunci pribadi dan publik ke dalam wadah p12 dengan openssl
- Ini adalah kunci Alamofire tanpa evaluasi dan dengan mengirimkan sertifikat klien
membuat instance PKCS512 () dan membuat URLCredential menggunakan itu (kode di tautan di atas) di alamofire semua yang Anda butuhkan dari tautan di atas adalah kelas PKCS12 dan ekstensi URLCredential
public class PKCS12 {
let label:String?
let keyID:NSData?
let trust:SecTrust?
let certChain:[SecTrust]?
let identity:SecIdentity?
public init(PKCS12Data:NSData,password:String)
{
let importPasswordOption:NSDictionary = [kSecImportExportPassphrase as NSString:password]
var items : CFArray?
let secError:OSStatus = SecPKCS12Import(PKCS12Data, importPasswordOption, &items)
guard secError == errSecSuccess else {
if secError == errSecAuthFailed {
NSLog("ERROR: SecPKCS12Import returned errSecAuthFailed. Incorrect password?")
}
fatalError("SecPKCS12Import returned an error trying to import PKCS12 data")
}
guard let theItemsCFArray = items else { fatalError() }
let theItemsNSArray:NSArray = theItemsCFArray as NSArray
guard let dictArray = theItemsNSArray as? [[String:AnyObject]] else { fatalError() }
func f<T>(key:CFString) -> T? {
for d in dictArray {
if let v = d[key as String] as? T {
return v
}
}
return nil
}
self.label = f(key: kSecImportItemLabel)
self.keyID = f(key: kSecImportItemKeyID)
self.trust = f(key: kSecImportItemTrust)
self.certChain = f(key: kSecImportItemCertChain)
self.identity = f(key: kSecImportItemIdentity)
}
}
extension URLCredential {
public convenience init?(PKCS12 thePKCS12:PKCS12) {
if let identity = thePKCS12.identity {
self.init(
identity: identity,
certificates: thePKCS12.certChain,
persistence: URLCredential.Persistence.forSession)
}
else { return nil }
}
}
- memasukkan kredensial tersebut untuk mengautentikasi (dengan: urlCredential) per sesi yang hilangDidReceiveChallenge di delegasi Alamofire 5
dan itu dia.
Kata sandi hardcode ke konstruktor p12 sangat jelek. Eww Kunci apa yang saya kira adalah base64 memanggang di p12 menjadi kode daripada menjadikannya sebagai file yang rentan terhadap ipa patcher attach.