我有一個使用自簽名的證書證明自己的身份,我和密鑰工具創建了一個簡單的Java服務器:kCFStreamPropertySocketSecurityLevel到kCFStreamSocketSecurityLevelNegotiatedSSL導致OSStatus errSSLXCertChainInvalid(-9807)連接到Java
System.setProperty("javax.net.ssl.keyStore", "../../pki/z-keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "ZZZZZZ");
System.setProperty("javax.net.debug", "all");
ServerSocketFactory serverSocketFactory = SSLServerSocketFactory
.getDefault();
ServerSocket serverSocket = serverSocketFactory
.createServerSocket(8443);
System.out.println("Waiting for connections on 8443");
final AtomicInteger nextSocketId = new AtomicInteger();
while (true) {
final Socket socket = serverSocket.accept();
new Thread(new Runnable() {
@Override
public void run() {
final int socketId = nextSocketId.getAndIncrement();
try {
System.out.println("Received connection from socketId: " + socketId);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter printWriter = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream()));
for (String line = bufferedReader.readLine(); line != null; line = bufferedReader
.readLine()) {
System.out.println("Read: " + line);
printWriter.println("Read: " + line);
}
bufferedReader.close();
printWriter.close();
} catch (SSLHandshakeException e) {
// don't care
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Closed connection from socketId: " + socketId);
}
}).start();
}
我連接到它與一個簡單的ios客戶端在iPhone模擬器運行:
- (void) connectSecurely {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL,
(CFStringRef)@"mcheath.local",
8443,
&readStream,
&writeStream);
NSDictionary *sslSettings = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanFalse, (id)kCFStreamSSLValidatesCertificateChain,
nil];
CFReadStreamSetProperty(readStream,
kCFStreamPropertySSLSettings,
sslSettings);
/* Turning on this setting makes the SSL handshake fail with OSStatus -9807 */
CFReadStreamSetProperty(readStream,
kCFStreamPropertySocketSecurityLevel,
kCFStreamSocketSecurityLevelNegotiatedSSL);
self.inputStream = (NSInputStream *)readStream;
self.outputStream = (NSOutputStream *)writeStream;
[self.inputStream setDelegate:self];
[self.outputStream setDelegate:self];
[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
CFReadStreamOpen(readStream);
CFWriteStreamOpen(writeStream);
}
#pragma mark -
#pragma mark NSStreamDelegate
- (void)stream:(NSStream *)aStream
handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventNone:
NSLog(@"NSStreamEventNone");
break;
case NSStreamEventOpenCompleted:
NSLog(@"NSStreamEventOpenCompleted");
break;
case NSStreamEventHasBytesAvailable:
NSLog(@"NSStreamEventHasBytesAvailable");
break;
case NSStreamEventHasSpaceAvailable:
NSLog(@"NSStreamEventHasSpaceAvailable");
break;
case NSStreamEventErrorOccurred:
NSLog(@"NSStreamEventErrorOccurred: %@", [aStream streamError]);
NSLog(@"SSL Settings: %@", [aStream propertyForKey:(NSString *) kCFStreamPropertySSLSettings]);
break;
case NSStreamEventEndEncountered:
NSLog(@"NSStreamEventEndEncountered");
break;
default:
break;
}
}
爲什麼設置kCFStreamPropertySocketSecurityLevel到kCFStreamSocketSecurityLevelNegotiatedSSL引起我的SSL握手失敗?
今天節省了我的一天。完全。 :) – 2013-10-22 09:16:23