![](/img/trans.png)
[英]Cannot establish TLS connection to Openfire 4.1.3 server with Smack 4.2 on Android: SSLProtocolException: SSL handshake aborted
[英]TLS Connection on iOS swift handshake issue
我在與Ingenico iPP320設備建立SSL / TLS連接時遇到問題。 我已經嘗試過這里建議的解決方案,但出現此錯誤
CFNetwork SSLHandshake failed (-9824 -> -9829)
我是使用SSL / TLS連接的新手,但不確定如何建立連接。 我正在使用的是一個受密碼保護的p12文件,該證書不是自簽名的。 有人告訴我,服務器也必須對客戶端進行身份驗證,因此中間和根CA可能必須發送到服務器。 我可以在Android上使用身份驗證,但是不確定在iOS中如何進行身份驗證。
以下是有效的Android代碼。
public SSLSocket createSSLSocket(String ipAddress, int port)
{
try
{
SSLSocket socket = null;
String certStorePassword = "password";
String certStoreType = "pkcs12";
InputStream iStream = getResources().openRawResource(R.raw.clientP12File);
KeyStore keyStore = KeyStore.getInstance(certStoreType);
keyStore.load(iStream, certStorePassword.toCharArray());
// KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, certStorePassword.toCharArray());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new SecureRandom());
SSLContext.setDefault(sc);
SSLSocketFactory factory = sc.getSocketFactory();
socket = (SSLSocket) factory.createSocket(ipAddress, port);
socket.setEnabledProtocols(new String[] { "TLSv1.2" });
socket.setUseClientMode(true);
socket.startHandshake();
return socket;
}
catch (Exception ex) {
Log.e(TAG, "createSSLSocket: ", ex);
}
return null;
}
對於嘗試使用P12證書進行TLS連接的其他人,這是我想出的解決方案。 如果有人有更好的方法,請告訴我謝謝。
//
// SSLConnection.swift
// SSLConnection
//
// Created by JC Castano on 3/27/17.
// Copyright © 2017 1stPayGateway. All rights reserved.
//
import Foundation
class SSLConnection: NSObject, StreamDelegate {
private static var inputStream:InputStream!
private static var outputStream:OutputStream!
private var ipAddress:String = ""
private var sslEnabled: Bool = false
public func connectToIngenico(address:String, sslEnabled: Bool) {
// TODO: Create dispatch queue to handle Ingenico connection
// initIngenicoQueue()
self.ipAddress = address
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocketToHost(nil, address as CFString!,12000, &readStream, &writeStream)
// Documentation suggests readStream and writeStream can be assumed to
// be non-nil. If you believe otherwise, you can test if either is nil
// and implement whatever error-handling you wish.
SSLConnection.inputStream = readStream!.takeRetainedValue()
SSLConnection.outputStream = writeStream!.takeRetainedValue()
SSLConnection.inputStream.delegate = self
SSLConnection.outputStream.delegate = self
SSLConnection.inputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
SSLConnection.outputStream.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
if sslEnabled {
// Enable SSL/TLS on the streams
SSLConnection.inputStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL, forKey: Stream.PropertyKey.socketSecurityLevelKey)
SSLConnection.outputStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL, forKey: Stream.PropertyKey.socketSecurityLevelKey)
let sslSettings = [
// NSStream automatically sets up the socket, the streams and creates a trust object and evaulates it before you even get a chance to check the trust yourself. Only proper SSL certificates will work with this method. If you have a self signed certificate like I do, you need to disable the trust check here and evaulate the trust against your custom root CA yourself.
NSString(format: kCFStreamSSLValidatesCertificateChain): kCFBooleanFalse,
// We are an SSL/TLS client, not a server
NSString(format: kCFStreamSSLIsServer): kCFBooleanFalse,
// Get the key chain items and add it to ssl settings
NSString(format: kCFStreamSSLCertificates): getKeyChain(fileName: "CLIENT", ofType: "p12", password: "password")
] as [NSString : Any]
SSLConnection.inputStream.setProperty(sslSettings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
SSLConnection.outputStream.setProperty(sslSettings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
}
SSLConnection.inputStream.open()
SSLConnection.outputStream.open()
}
func getKeyChain(fileName: String, ofType type: String, password: String) -> CFArray {
let mainBundle = Bundle.main
let thePath = mainBundle.path(forResource: fileName, ofType: type)!
let PKCS12Data: NSData = NSData(contentsOfFile: thePath)!
var items: CFArray?
let optionDict: NSMutableDictionary = [kSecImportExportPassphrase as NSString: password]
let sanityCheck = SecPKCS12Import(PKCS12Data, optionDict, &items)
if sanityCheck == errSecSuccess && CFArrayGetCount(items) > 0 {
return parseKeyChainItems(items!)
} else {
switch sanityCheck {
case errSecSuccess:
print("Error importing p12: errSecSuccess")
case errSecUnimplemented:
print("Error importing p12: errSecUnimplemented")
case errSecIO:
print("Error importing p12: errSecIO")
case errSecOpWr:
print("Error importing p12: errSecOpWr")
case errSecParam:
print("Error importing p12: errSecParam")
case errSecAllocate:
print("Error importing p12: errSecAllocate")
case errSecUserCanceled:
print("Error importing p12: errSecUserCanceled")
case errSecBadReq:
print("Error importing p12: errSecBadReq")
case errSecInternalComponent:
print("Error importing p12: errSecInternalComponent")
case errSecNotAvailable:
print("Error importing p12: errSecNotAvailable")
case errSecDuplicateItem:
print("Error importing p12: errSecDuplicateItem")
case errSecItemNotFound:
print("Error importing p12: errSecItemNotFound")
case errSecInteractionNotAllowed:
print("Error importing p12: errSecInteractionNotAllowed")
case errSecDecode:
print("Error importing p12: errSecDecode")
case errSecAuthFailed:
print("Error importing p12: errSecAuthFailed")
default:
print("Error importing p12: Unknown items: \(items)")
break
}
}
return [] as CFArray
}
func parseKeyChainItems(_ keychainArray: NSArray) -> CFArray {
print("Key chain array: \(keychainArray)")
let dict = keychainArray[0] as! Dictionary<String,AnyObject>
let key = String(kSecImportItemIdentity)
let identity = dict[key] as! SecIdentity?
let certArray:[AnyObject] = dict["chain"] as! [SecCertificate]
var certChain:[AnyObject] = [identity!]
for item in certArray {
certChain.append(item)
}
return certChain as CFArray
}
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
let streamName = getStreamName(aStream)
switch eventCode {
case Stream.Event.openCompleted:
print("\(streamName).OpenCompleted")
break
case Stream.Event.hasBytesAvailable:
print("\(streamName).HasBytesAvailable")
case Stream.Event.hasSpaceAvailable:
print("\(streamName).HasSpaceAvailable")
break
case Stream.Event.endEncountered:
print("\(streamName).EndEncountered")
break
case Stream.Event.errorOccurred:
print("\(streamName).ErrorOccurred")
break
default:
print("\(streamName) unknown event")
break
}
}
func getStreamName(_ aStream: Stream) -> String {
if comparedStreamEqual(aStream, bStream: SSLConnection.inputStream) {
return "InputStream"
} else if comparedStreamEqual(aStream, bStream: SSLConnection.outputStream) {
return "OutputStream"
}
return "UnknownStream"
}
func comparedStreamEqual(_ aStream: Stream? , bStream: Stream?) -> Bool {
if aStream != nil && bStream != nil {
if aStream == bStream {
return true
}
}
return false
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.