我使用SSL在用Java编写的两个组件之间进行通信.我不能使用CA,所以我必须自我签名.不幸的是,这意味着当我尝试握手时,我得到一个SunCertPathBuilderException.我可以创建我自己的X509TrustManager,它只信任所有东西,但这种方式违背了签署证书的目的.
我想,在第一次建立连接时,提示用户"使用无效证书进行SSL握手.将证书添加到商店?" 或类似的东西,所以他们可以将它添加到他们的证书商店,就像网页浏览器在无效证书的网站上做的那样.我可以在网上找到很多通过命令行向商店添加证书的例子,但我无法弄清楚如何以编程方式进行.有没有办法做到这一点?
TL,博士;是否有本地 Java17 解决方案来生成自签名证书,无论是通过标准库(不太可能)还是通过一些轻量级库?
还有一个类似的问题(我问过Access `sun.security.x509` in JDK 11 without module?),因为从 JDK11 开始,对内部 JDK 包的访问受到限制,因此无法使用sun.security.x509. 直到 JDK17 为止,都可以通过某些编译器配置来标记打开这些包来规避它。JDK17 改变了这一点,删除了该选项。
从我能够收集到的当前解决方案是:
keytooljava工具,但这有两个缺点:调用外部工具速度较慢,并且需要创建密钥库文件。目前(2)在我的用例中似乎更方便,但我很想找到第三个选项 - 本机、轻量级解决方案。
编辑:有 OpenJDK 问题:JDK-8058778:用于创建证书和证书请求的新 API,我希望有一天它会被实现......
我的目标是在用C#编写的Java服务器和客户端之间建立安全通信.
java服务器代码:
System.setProperty("javax.net.ssl.keyStore","cert/mySrvKeystore");
System.setProperty("javax.net.ssl.keyStorePassword","myPassword");
SSLServerSocketFactory sslserversocketfactory =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslserversocket = = (SSLServerSocket) sslserversocketfactory.createServerSocket(2389);
while(true) {
System.err.println("server w8 new connection");
try {
SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
//sslsocket.startHandshake();
in = sslsocket.getInputStream();
out = sslsocket.getOutputStream();
out.flush();
String response = new String(receiveMessage());
while (response != "end") {
System.out.println("Server recv="+response);
response = new String(receiveMessage());
sendMessage(("echo="+response).getBytes());
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
和用c#编写的客户端:
client = new TcpClient() { SendTimeout = 5000, ReceiveTimeout = 5000 };
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(host), …Run Code Online (Sandbox Code Playgroud) 我想生成一个密钥对,并以编程方式将其插入Java KeyStore。我可以使用命令行来完成我想要的事情,但是如何使用Java代码来做到这一点呢?
这是命令行:
keytool -genkeypair \
-dname "cn=Unknown" \
-alias main \
-keyalg RSA \
-keysize 4096 \
-keypass 654321 \
-keystore C:\\Users\\Felipe\\ks \
-storepass 123456 \
-validity 365
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止拥有的Java代码:
public static void main(String[] args) {
try (
FileOutputStream fos = new FileOutputStream("C:\\Users\\Felipe\\ks");
) {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096, SecureRandom.getInstance("SHA1PRNG"));
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Certificate[] chain = {};
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setKeyEntry("main", keyPair.getPrivate(), "654321".toCharArray(), chain); // Error: Private key must be accompanied by certificate chain
keyStore.store(fos, …Run Code Online (Sandbox Code Playgroud) 我创建了密钥库,我只想在密钥库中存储publickey,并且不想存储私钥.因为私钥将在客户端设备中,并且他将使用rest API共享公钥.
另外,我应该如何在一个keystore中使用不同的别名保留多个公钥
如果某人有示例代码或示例链接,那么对我来说将非常有帮助.