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

发布于 2024-09-24 23:06:42 字数 3886 浏览 10 评论 0原文

我在网络应用程序中使用的密钥库文件上周已过期。我很久以前就生成了它。所以我开始使用 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"

按照commnad为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)

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

Keystore files I have used in my web application expired last week. I generated it long time ago. So I started generating new certificate using keytool. I used this certificate to connect a transaction server and the web server. I wanted to use self signed certificate for this application. I generate it using following command to generate self signed key for transaction server.

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"

following commnad to generate keystore for web application

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"

I used following code in the transaction server to create the socket connection

          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);

But it gives following exception when I used it in my application and try to connect to the transaction server through web server

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)

Please can any one tell me where is the problem

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

桃气十足 2024-10-01 23:06:42

首先,避免直接使用com.sun.net.ssl包和类。 JSSE 的架构是为了让您可以使用工厂并稍后指定提供者而构建的。请改用 javax.net.ssl.TrustManagerFactory(与 KeyManagerFactory 和 SSLContext 相同)。 (我建议使用 "PKIX" 而不是 "SunX509" 作为信任管理器算法,因为它通常是 Sun 提供商的默认值,或者更好,使用 >TrustManagerFactory.getDefaultAlgorithm())。

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

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

生成证书时,应确保使用 CN=the.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 和 client-truststore 分别替换为 client-keystore 和 server-truststore。

在这种情况下,server-keystore.jksserver-truststore.jks 可能是同一文件,但您不需要这样做(在客户端也是如此)。

Firstly, avoid using the com.sun.net.ssl packages and classes directly. The architecture of the JSSE is built so that you can use the factories and specify the providers later. Use javax.net.ssl.TrustManagerFactory (same for KeyManagerFactory and SSLContext) instead. (I'd suggest using "PKIX" instead of "SunX509" for the trust manager algorithm, as it's normally the default with the Sun provider, or better, use TrustManagerFactory.getDefaultAlgorithm()).

Secondly, you don't need to set up a keymanager on the client side unless you're using client-certificate authentication.

Finally (and perhaps the most important), you need to export the self-signed certificate you've generated on the server side (only the certificate, not the private key) and import it into the keystore you use as a trust store on the client side.

When you generate the certificate, you should make sure you use CN=the.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

If you want to use client-certificate authentication, you need to repeat the operation by replacing server-keystore and client-truststore with client-keystore and server-truststore respectively.

In this case, server-keystore.jks and server-truststore.jks could be the same file, but you don't need to (same on the client side).

忆梦 2024-10-01 23:06:42

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

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

All you needed to do was keytool -selfcert - alias XXX -validity DDD where XXX is the same alias as before and DDD is the number of days before expiry, for the server cert, then export that cert and import into the client's truststore. Repeat in reverse for the client. You've left out the export/import part.

However much of that code is now obsolete. You don't need to call addProvider(), and you can change com.sun.net.ssl to javax.net.ssl throughout the remainder.

乄_柒ぐ汐 2024-10-01 23:06:42

要理解这一点,您必须了解证书的工作原理。

由于任何人都可以创建证书(就像您一样),因此仅仅创建证书是不够的 - 证书必须是可信的。仅当证书由另一个受信任的证书签名时,该证书才受信任。
在信任“食物链”的顶端有几个主要的 CA,您可以向他们付费以使您的证书“受到公众信任”(您的计算机上安装了他们的证书)。

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

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

To understand this you have to understand how certificates work.

Since anyone can create a certificate (like you did), it is not enough just to create it - certificates have to be trusted. A certificate is trusted only if it is signed by another certificate, which is trusted.
On the top of the trust "food chain" there are several major CAs, to whom you can pay money to have your certificate "publicly trusted" (your computer comes with their certificates installed on it).

Of course you don't have to pay to a CA in order your application, BUT you have to mimic this behavior. What you will probably have to do is export the server/client public key, and install it in some kind of trusted store.

Check how your API allows you to define where your trusted certificates are.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文