ios, alamofire5: нужен эквивалент curl --key foo.key --cert foo, pem --location --request GET 'https: //bar.baz/foo "
У меня есть закрытый ключ в дополнение к открытому ключу для закрепления сертификата.
Как пройти аутентификацию на сервере?
$ file *
foo.der: data
foo.private.der: data
полученный с openssl из
foo.key: PEM RSA private key
foo.pem: PEM certificate
то, что мне нужно, это эквивалент этого alamofire:
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!"
работает
$ curl --cert ./client.pem --location --request GET 'https: // someurl / v1 / welcome /' curl: (58) невозможно установить файл закрытого ключа: './client.pem' типа PEM
не
Поэтому предложения использовать сам сертификат без закрытого ключа не работают.
Имеем ли мы дело с закреплением сертификата здесь или с учетом наличия закрытого ключа, здесь происходит что-то еще ???
Ответы
Вы можете создать в ServerTrustManagerкачестве параметра передачу ваших оценщиков для каждого имени хоста. Для закрепления открытого ключа используйте PublicKeysTrustEvaluatorследующее:
let evaluators: [String : ServerTrustEvaluating] = [
"your.host.com": PublicKeysTrustEvaluator(performDefaultValidation: false, validateHost: false)
]
let serverTrustManager = ServerTrustManager(evaluators: evaluators)
Для закрепления сертификата используйте PinnedCertificatesTrustEvaluatorследующее:
let evaluators: [String : ServerTrustEvaluating] = [
"your.host.com": PinnedCertificatesTrustEvaluator(
acceptSelfSignedCertificates: true,
performDefaultValidation: false,
validateHost: false
)
]
let serverTrustManager = ServerTrustManager(evaluators: evaluators)
Оба метода требуют, чтобы ваш сертификат был включен в ваш комплект как файл .cerили .der.
После создания ServerTrustManagerпередайте его Sessionэкземпляру и используйте его для своих запросов:
let session = Session(serverTrustManager: serverTrustManager)
Если вы хотите иметь более сложную логику того, как вы проверяете свой сервер или вам нужно использовать подстановочные знаки в своем домене, вам необходимо создать подкласс ServerTrustManagerи переопределить serverTrustEvaluator(forHost:)функцию:
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)
}
}
- упакованный закрытый и открытый ключ в контейнер p12 с помощью openssl
- это был ключевой Alamofire без оценки и с отправкой клиентского сертификата
создал экземпляр PKCS512 () и создал URLCredential, используя это (код в ссылке выше) в alamofire, все, что вам нужно по ссылке выше, - это класс PKCS12 и расширение 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 }
}
}
- подали эти учетные данные для аутентификации (с: urlCredential) на отсутствующий sessionDidReceiveChallenge в делегате Alamofire 5
вот и все.
Жесткое кодирование пароля в конструкторе p12 было ужасно некрасивым. Эвв, что ключ, я думаю, это запекание base64 в p12 в код, а не в виде файла, подверженного прикреплению ipa patcher.