Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用jdk中提供的keytool生成SSL证书_Java_Ssl_Certificate_Keytool - Fatal编程技术网

Java 使用jdk中提供的keytool生成SSL证书

Java 使用jdk中提供的keytool生成SSL证书,java,ssl,certificate,keytool,Java,Ssl,Certificate,Keytool,我在web应用程序中使用的密钥库文件已于上周过期。我很久以前就生成了它。所以我开始使用keytool生成新证书。我使用此证书连接事务服务器和web服务器。我想为这个应用程序使用自签名证书。我使用以下命令为事务服务器生成自签名密钥 keytool -genkey -keystore keys/SvrKeyStore -keyalg rsa -validity 365 -alias Svr -storepass 123456 -keypass abcdefg -dname "CN=One1, OU=

我在web应用程序中使用的密钥库文件已于上周过期。我很久以前就生成了它。所以我开始使用keytool生成新证书。我使用此证书连接事务服务器和web服务器。我想为这个应用程序使用自签名证书。我使用以下命令为事务服务器生成自签名密钥

keytool -genkey -keystore keys/SvrKeyStore -keyalg rsa -validity 365 -alias Svr -storepass 123456 -keypass abcdefg -dname "CN=One1, OU=Development1, O=One, L=Bamba, S=Western Prov1, C=S1"
遵循命令为web应用程序生成密钥库

keytool -genkey -keystore keys/ClientKeyStore -keyalg rsa -validity 365 -alias Web -storepass 123456 -keypass abcdefg -dname "CN=One, OU=Development, O=One, L=Bamba, S=Western Prov, C=SL"
我在事务服务器中使用了以下代码来创建套接字连接

          String KEYSTORE = Config.KEYSTORE_FILE;//SvrKeyStore  keystore file
          char[] KEYSTOREPW = "123456".toCharArray();
          char[] KEYPW = "abcdefg".toCharArray();
          com.sun.net.ssl.TrustManagerFactory tmf;

          boolean requireClientAuthentication;

          java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.
                                             Provider());
          java.security.KeyStore keystore = java.security.KeyStore.getInstance(
              "JKS");
          keystore.load(new FileInputStream(KEYSTORE), KEYSTOREPW);

          com.sun.net.ssl.KeyManagerFactory kmf = com.sun.net.ssl.
              KeyManagerFactory.getInstance("SunX509");
          kmf.init(keystore, KEYPW);

          com.sun.net.ssl.SSLContext sslc = com.sun.net.ssl.SSLContext.
              getInstance("SSLv3");
          tmf = com.sun.net.ssl.TrustManagerFactory.getInstance("sunx509");
          tmf.init(keystore);

          sslc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
          SSLServerSocketFactory ssf = sslc.getServerSocketFactory();
          SSLServerSocket ssocket = (SSLServerSocket) ssf.createServerSocket(port);
          ssocket.setNeedClientAuth(true);
但当我在应用程序中使用它并尝试通过web服务器连接到事务服务器时,它会出现以下异常

javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHands
hakeException: java.security.cert.CertificateException: Untrusted Server Certifi
cate Chain
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.jav
a:1172)
        at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:
65)
        at net.schubart.fixme.internal.MessageInput.readExactly(MessageInput.jav
a:166)
        at net.schubart.fixme.internal.MessageInput.readMessage(MessageInput.jav
a:78)
        at cc.aot.itsWeb.ClientWriterThread.run(ClientWriterThread.java:241)
        at java.lang.Thread.run(Thread.java:619)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateEx
ception: Untrusted Server Certificate Chain
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1
520)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:182)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:176)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien
tHandshaker.java:975)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHa
ndshaker.java:123)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:5
11)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.jav
a:449)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.j
ava:817)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SS
LSocketImpl.java:1029)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.
java:621)
        at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.ja
va:59)
        at java.io.OutputStream.write(OutputStream.java:58)

请任何人告诉我问题出在哪里

对于服务器证书,您需要做的只是keytool-selfcert-alias XXX-validity DDD,其中XXX是与以前相同的别名,DDD是到期前的天数,然后导出该证书并导入客户端的信任库。对客户端反向重复。您遗漏了导出/导入部分


然而,这些代码中的大部分现在已经过时了。您不需要调用addProvider(),并且可以在其余的过程中将com.sun.net.ssl更改为javax.net.ssl

要理解这一点,您必须了解证书是如何工作的

因为任何人都可以创建一个证书(就像你做的那样),仅仅创建它是不够的——证书必须是可信的。仅当证书由另一个受信任的证书签名时,该证书才受信任。 在信任“食物链”的顶端有几个主要的CA,你可以付钱让他们“公开信任”你的证书(你的计算机上安装了他们的证书)

当然,您不必为应用程序向CA付费,但您必须模仿这种行为。您可能需要做的是导出服务器/客户机公钥,并将其安装在某种可信存储中


检查API如何允许您定义受信任证书的位置。

首先,避免直接使用
com.sun.net.ssl
包和类。JSSE的体系结构是这样构建的,以便您以后可以使用工厂并指定提供者。使用
javax.net.ssl.TrustManagerFactory
(与
KeyManagerFactory
SSLContext
相同)。(我建议对信任管理器算法使用
“PKIX”
而不是
“SunX509”
,因为这通常是Sun提供程序的默认值,或者更好地使用
TrustManagerFactory.getDefaultAlgorithm()

其次,除非使用客户端证书身份验证,否则不需要在客户端设置密钥管理器

最后(也许是最重要的),您需要导出您在服务器端生成的自签名证书(只有证书,而不是私钥),并将其导入到您在客户端用作信任存储的密钥库中

生成证书时,应确保使用
CN=server.host.name

keytool -genkey -keystore server-keystore.jks -alias server_alias \
        -dname "CN=the.server.host.name,OU=whateveryoulike" \
        -keyalg "RSA" -sigalg "SHA1withRSA" -keysize 2048 -validity 365

keytool -export -keystore server-keystore.jks -alias server_alias -file server.crt

keytool -import -keystore client-truststore.jks -file server.crt
如果要使用客户端证书身份验证,则需要通过分别用客户端密钥库和服务器信任库替换服务器密钥库和客户端信任库来重复该操作

在这种情况下,
server keystore.jks
server truststore.jks
可以是同一个文件,但不需要(在客户端相同)