gpt4 book ai didi

java - SSL 套接字连接 : CFNetwork SSLHandshake failed (-9824) connecting to Java SSLServerSocket

转载 作者:行者123 更新时间:2023-11-29 03:29:26 25 4
gpt4 key购买 nike

我正在使用 Java 中的 SSLServerSocket 类设置安全套接字连接,然后使用 objective-c 中的 Stream 类(CF 和 NS)。我已经使用以下代码进行了设置:

Java SSLServerSocket 代码(SecureClientWorker 处理每个连接):

public void listenSocket(int port){
try {
System.setProperty("javax.net.ssl.keyStore", "path/to/certificate(signed_by_own_root_certificate).jks");
//I try to make this root certificate trusted by iOS (see obj-c code below)
System.setProperty("javax.net.ssl.keyStorePassword", "PASSWORD...");
} catch (IOException e1) {
e1.printStackTrace();
}
try{
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
server = (SSLServerSocket) ssf.createServerSocket(port);

logger.info("Started to listen on port: "+port);
}catch(Exception e){
logger.warning("Could not listen on port: "+port);
e.printStackTrace();
}

while(running){
SecureClientWorker w;
try{
w = new SecureClientWorker(server.accept(), this);
Thread t = new Thread(w);
t.start();
}catch(IOException e){
if(running)
e.printStackTrace();
}
}

}

Objective C 客户端代码:

[self addRootCert]; //This is where I attempt to make the root certificate trusted, If needed I can post it
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)self.ip.text, self.portNumber.text.intValue, &readStream, &writeStream);

// Set options then bridge to ARC:
NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
(id)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamPropertySocketSecurityLevel,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
nil];

if (readStream) {
CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (__bridge CFDictionaryRef)settings);
inStream = (__bridge_transfer NSInputStream*) readStream;
[inStream setDelegate:self];
[inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inStream open];
}

if (writeStream) {
CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (__bridge CFDictionaryRef)settings);
outStream = (__bridge_transfer NSOutputStream*) writeStream;
[outStream setDelegate:self];
[outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outStream open];
}

但是这会导致错误代码 CFNetwork SSLHandshake failed (-9824) 并且 inStream 对象在 NSStreamDelegate 方法中返回错误 NSStreamEventErrorOccurred .

在 Java 端,一个 IOException 似乎被抛出并带有以下内容:

in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); //ClientSocket is just the connection to the client
[...]
in.readLine();

printStackTrace 说:javax.net.ssl.SSLHandshakeException: no cipher suites in common

我是否必须创建一个 KeyManager(正如我在其他地方读到的那样)?我该怎么做(请从无到有打开的 SSLServerSocket)?

如有任何帮助,我们将不胜感激!

编辑

我更改了服务器代码,因为它可能无法设置系统属性。

我的新代码是:

KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream ksIs = new FileInputStream(new File("path/to/certificate(signed_by_own_root_certificate).jks"));
try {
ks.load(ksIs, "PASSWORD...".toCharArray());
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (ksIs != null) {
ksIs.close();
}
}

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "PASWD".toCharArray());
KeyManager keyManagers[] = kmf.getKeyManagers();
SSLContext sc = SSLContext.getDefault();
sc.init(keyManagers, null, new SecureRandom());
SSLServerSocketFactory socketFactory = sc.getServerSocketFactory();

server = (SSLServerSocket) socketFactory.createServerSocket(port);

但是我现在收到此错误消息:java.security.KeyManagementException:自动初始化默认 SSLContext

经过一些研究,我尝试制作自己的 TrustManager 但仍然无法正常工作

我错过了什么?

最佳答案

假设您的应用程序可以读取 keystore 文件并且密码是正确的,我的猜测是您在获取此套接字工厂之前已经在您的 Java 应用程序中的某个地方使用了 SSL/TLS 连接(这可能已完成隐含地由另一个库)。

javax.net.ssl.keyStore* 系统属性仅用于初始化默认的 SSLContext 一次。在初始化该上下文后更改它们将无济于事。

javax.net.ssl.SSLHandshakeException: no cipher suites in common 错误消息是典型的未找到或未正确加载 keystore 的情况。这是因为在没有任何证书/ key Material 的情况下,没有启用任何 RSA/DSA 密码套件:这些是远程客户端将要查找的密码套件。

检查这一点的快速方法是在命令行上设置这些属性,或者在应用程序的最开始设置它们(而不是在服务器代码的其他地方更改它们)。

如果您需要这些设置在您的应用程序中不是全局的,您确实需要初始化一个 KeyManager


在您编辑之后,java.security.KeyManagementException: Default SSLContext is initialized automatically 发生是因为您正在尝试重新配置默认 SSLContext。改用新实例:

SSLContext sc = SSLContext.getInstance("TLS");

关于java - SSL 套接字连接 : CFNetwork SSLHandshake failed (-9824) connecting to Java SSLServerSocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19160684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com