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' “你好哇!”

有效

$ 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)
    }
}
,
  1. 使用openssl将私钥和公钥打包到p12容器中
  2. 这是关键Alamofire without evaluation and with sending client certificate

创建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 }
    }
}
  1. 输入该凭据进行身份验证(使用:urlCredential) 每个Missing sessionDidReceiveChallenge in Alamofire 5 delegate

就是这样。

将密码硬编码到p12构造函数中非常难看。 EWW 我想关键是要在p12中将base64烘焙到代码中,而不是将其作为易于ipa修补程序附加的文件。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...