Swift 在web服务器iOS应用程序上安装TLS证书
我正在尝试将Swish payment集成到我开发的一个应用程序中。 为了能够连接到SwishAPI,我必须根据文档“从SwishCertificateManagement设置TLS证书,并将其安装在”我的“web服务器”上。以下是完整的技术文档 我不明白的问题是,我不使用web服务器,也不能在那里安装这些证书 我的应用程序只是为客户提供了一些服务,在按下支付按钮后,应该会打开Swish应用程序来完成交易 我尝试的是发出post请求以获取请求令牌,我可以使用该令牌打开加载了付款详细信息的swish应用程序。 我确信问题出在证书上,但是找不到一个好的来源来解释如何导入(集成)它们 让strURL=“” guard let postrl=URL(字符串:strURL)else{ 打印(“无法创建url”) 返回 }Swift 在web服务器iOS应用程序上安装TLS证书,swift,swish,Swift,Swish,我正在尝试将Swish payment集成到我开发的一个应用程序中。 为了能够连接到SwishAPI,我必须根据文档“从SwishCertificateManagement设置TLS证书,并将其安装在”我的“web服务器”上。以下是完整的技术文档 我不明白的问题是,我不使用web服务器,也不能在那里安装这些证书 我的应用程序只是为客户提供了一些服务,在按下支付按钮后,应该会打开Swish应用程序来完成交易 我尝试的是发出post请求以获取请求令牌,我可以使用该令牌打开加载了付款详细信息的swis
var request = URLRequest(url: postURL)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let data: [String: Any] = [
"callbackUrl": "https://example.com/api/swishcb/paymentrequests",
"payeeAlias": "123xxxxxxx", // The Swish number of the payee. It needs to match with Merchant Swish number.
"amount": "100",
"currency": "SEK",
"message": "Test request to get the token"
]
do {
let jsonParams = try JSONSerialization.data(withJSONObject: data, options: [])
request.httpBody = jsonParams
} catch {
print("Error serializing the parameters of the post request")
return
}
// response will contain a Token, unique for each payment request
let config = URLSessionConfiguration.default
config.timeoutIntervalForResource = 120
config.timeoutIntervalForRequest = 120
let session = URLSession(configuration: config)
session.dataTask(with: request) { (data, response, error) in
print("Data \(data)")
print("Response \(response)")
if error != nil {
print("Error post request \(error?.localizedDescription)")
}
}.resume()
我得到的错误是:
错误post请求可选(“发生SSL错误,无法与服务器建立安全连接。”)
018-12-21 12:24:55.549759+0200 tolk-24-7[7230:111102][BoringSSL]BoringSSL\u上下文\u警报\u回调\u处理程序(3718)[C6.1:2][0x7fce4a77bf00]警报级别:致命,描述:握手失败
2018-12-21 12:24:55.550047+0200 tolk-24-7[7230:111102][BoringSSL]BoringSSL_会话_错误日志(224)[C6.1:2][0x7fce4a77bf00][BoringSSL_会话_握手不完整]SSL_错误_SSL(1):库内的操作失败
2018-12-21 12:24:55.550332+0200 tolk-24-7[7230:111102][BoringSSL]BoringSSL会话、握手错误、打印(205)[C6.1:2][0x7fce4a77bf00]140523985879704:错误:10000410:SSL例程:OPENSSL_内部:SSLV3_警报_握手_失败:/BuildRoot/Library/Caches/com.apple.xbs/Sources/boringssl_Sim/boringssl-109.220.4/SSL/tls_record.cc:586:SSL警报号40
2018-12-21 12:24:55.550585+0200 tolk-24-7[7230:111102][BoringSSL]BoringSSL上下文获取错误代码(3539)[C6.1:2][0x7fce4a77bf00]SSL AD握手失败
2018-12-21 12:24:55.552299+0200 tolk-24-7[7230:111102]TIC TCP连接失败[6:0x600002dd6c40]:3:-9824错误(-9824)
2018-12-21 12:24:55.555924+0200 tolk-24-7[7230:111102]NSURLSession/NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9824)
2018-12-21 12:24:55.556052+0200 tolk-24-7[7230:111102]任务。HTTP加载失败(错误代码:-1200[3:-9824])
2018-12-21 12:24:55.556234+0200 tolk-24-7[7230:111613]任务。完成错误-代码:-1200我感到您的失望,我还没有使用SwishAPI本身,但看起来URLSession无法执行客户端证书请求。那一步握手失败了 有一个选项可以将URLSessionDelegate添加到URLSession,以处理身份验证挑战,如ServerTrust和ClientCertificate。他们正在这里讨论: 如果您能够使用客户端证书和私钥创建p12/pfx,则可以使用SecPKCS12Import将其导入,并将其用于在URLSessionLegate中接收的NSURLAuthenticationMethodClientCertificate中的URLCredential信任。下面是我编写的一个实现:
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
{
let authenticationMethod = challenge.protectionSpace.authenticationMethod
if authenticationMethod == NSURLAuthenticationMethodServerTrust {
//Handle server trust if necessary
} else if authenticationMethod == NSURLAuthenticationMethodClientCertificate {
if let clientCredential = try? getClientUrlCredential() {
completionHandler(.useCredential, clientCredential)
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
}
getClientUrlCredential函数:
private func getClientUrlCredential() throws -> URLCredential {
let p12Data = getP12Data() //Get the data from the bundle if it's bundled in the app
let p12Key = getP12Key() //you need the key set for creating the p12/pfx
let certOptions: NSDictionary = [
kSecImportExportPassphrase as NSString : p12Key as NSString
]
// import certificate to read its entries
var items: CFArray?
let status = SecPKCS12Import(p12Data, certOptions, &items)
if status == errSecSuccess,
let items = items,
let dict = (items as Array).first as? [String: AnyObject],
let certChain = dict[kSecImportItemCertChain as String] as? [SecTrust] {
// Check if SecIdentityGetTypeID is present
guard let cfIdentity = dict[kSecImportItemIdentity as String] as CFTypeRef?,
CFGetTypeID(cfIdentity) == SecIdentityGetTypeID() else {
throw URLSessionPinningDelegateError.localClientCertificateError
}
let identity = dict[kSecImportItemIdentity as String] as! SecIdentity
return URLCredential(
identity: identity,
certificates: certChain,
persistence: .forSession
)
}
//Failed to read local certificate, throw error
throw URLSessionPinningDelegateError.localClientCertificateError
}
有了有效的客户机证书,您应该能够完成客户机hello并向服务器设置TLS,因为这似乎是您现在失败的地方。BoringSSL提供的SSL警报编号40至少对我来说是这样的
希望这至少为您指明了正确的方向,如果需要,欢迎进一步支持