我正在创建一个HTTPS服务器并自行验证证书。
我有一个奇怪的错误。
当我生成证书并添加该密钥库时,我能够进行SSL握手。
keytool -genkey -keyalg rsa -alias mycert -keystore lig.keystore -storepass changeit -keypass changeit
然而,当我使用keytool导入证书并将其添加到密钥库时,我收到SSH Handshake Failure
错误。
keytool -noprompt -importcert -file certDer -alias mycert -keystore lig.keystore -storepass changeit -keypass changeit
确切地说,第一个是自签名证书。第二个是第三方证书。
SSLHandshake适用于自签名证书,但不适用于第三方证书。
有谁可以告诉为什么?
HttpsNetServer.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
public class HttpsNetServer {
public static void main(String args[]) throws Exception {
SSLContext context;
KeyManagerFactory kmf;
KeyStore ks;
char[] storepass = "changeit".toCharArray();
char[] keypass = "changeit".toCharArray();
String storename = "/home/krishnan/.keystore";
context = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
FileInputStream fin = new FileInputStream(storename);
ks = KeyStore.getInstance("JKS");
ks.load(fin, storepass);
kmf.init(ks, keypass);
context.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = context.getServerSocketFactory();
ServerSocket ss = ssf.createServerSocket(8000);
Socket s = ss.accept();
PrintStream out = new PrintStream(s.getOutputStream());
out.println("Hi");
out.close();
s.close();
}
}
HttpsNetClient.java
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.cert.CertPath;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HttpsNetClient {
public static void main(String args[]) throws Exception {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, // No Key Manager
new TrustManager[] { new X509TrustManager()
{
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException
{}
@Override
public void checkServerTrusted(X509Certificate[] xcert, String arg1)
throws CertificateException {
System.out.println("Certificate");
/* for( X509Certificate certificate : xcert)
{
System.out.println(certificate.toString());
}*/
// check the certs
}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return null;
}
} }, // TrustManager
null);
SSLSocketFactory factory = context.getSocketFactory();
SSLSocket socket = (SSLSocket) factory.createSocket("127.0.0.1", 8000);
socket.startHandshake();
SSLSession session = socket.getSession();
java.security.cert.Certificate[] servercerts = session.getPeerCertificates();
List mylist = new ArrayList();
for (int i = 0; i < servercerts.length; i++) {
mylist.add(servercerts[i]);
}
CertificateFactory cf = CertificateFactory.getInstance("X.509");
CertPath cp = cf.generateCertPath(mylist);
FileOutputStream f = new FileOutputStream("CertPath.dat");
ObjectOutputStream b = new ObjectOutputStream(f);
b.writeObject(cp);
}
}
控制台输出
trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie: GMT: 1388082990 bytes = { 150, 135, 207, 23, 25, 26, 29, 28, 215, 141, 166, 204, 95, 134, 251, 101, 171, 119, 173, 127, 35, 182, 181, 72, 56, 81, 36, 68 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
[write] MD5 and SHA1 hashes: len = 163
0000: 01 00 00 9F 03 01 53 BC 77 2E 96 87 CF 17 19 1A ......S.w.......
0010: 1D 1C D7 8D A6 CC 5F 86 FB 65 AB 77 AD 7F 23 B6 ......_..e.w..#.
0020: B5 48 38 51 24 44 00 00 38 C0 0A C0 14 00 35 C0 .H8Q$D..8.....5.
0030: 05 C0 0F 00 39 00 38 C0 09 C0 13 00 2F C0 04 C0 ....9.8...../...
0040: 0E 00 33 00 32 C0 07 C0 11 00 05 C0 02 C0 0C C0 ..3.2...........
0050: 08 C0 12 00 0A C0 03 C0 0D 00 16 00 13 00 04 00 ................
0060: FF 01 00 00 3E 00 0A 00 34 00 32 00 17 00 01 00 ....>...4.2.....
0070: 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 18 00 ................
0080: 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 11 00 ................
0090: 02 00 12 00 04 00 05 00 14 00 08 00 16 00 0B 00 ................
00A0: 02 01 00 ...
main, WRITE: TLSv1 Handshake, length = 163
[Raw write]: length = 168
0000: 16 03 01 00 A3 01 00 00 9F 03 01 53 BC 77 2E 96 ...........S.w..
0010: 87 CF 17 19 1A 1D 1C D7 8D A6 CC 5F 86 FB 65 AB ..........._..e.
0020: 77 AD 7F 23 B6 B5 48 38 51 24 44 00 00 38 C0 0A w..#..H8Q$D..8..
0030: C0 14 00 35 C0 05 C0 0F 00 39 00 38 C0 09 C0 13 ...5.....9.8....
0040: 00 2F C0 04 C0 0E 00 33 00 32 C0 07 C0 11 00 05 ./.....3.2......
0050: C0 02 C0 0C C0 08 C0 12 00 0A C0 03 C0 0D 00 16 ................
0060: 00 13 00 04 00 FF 01 00 00 3E 00 0A 00 34 00 32 .........>...4.2
0070: 00 17 00 01 00 03 00 13 00 15 00 06 00 07 00 09 ................
0080: 00 0A 00 18 00 0B 00 0C 00 19 00 0D 00 0E 00 0F ................
0090: 00 10 00 11 00 02 00 12 00 04 00 05 00 14 00 08 ................
00A0: 00 16 00 0B 00 02 01 00 ........
[Raw read]: length = 5
0000: 15 03 01 00 02 .....
[Raw read]: length = 2
0000: 02 28 .(
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1961)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at HttpsNetClient.main(HttpsNetClient.java:49)
答案 0 :(得分:1)
第三方证书不应作为&#39; mycert&#39;导入。它不是你的证明,而是别人的证明。此外,您刚刚破坏了自己的密钥对和证书。重新开始,使用第三方证书的其他别名。
答案 1 :(得分:0)
问题是密钥库必须包含公共证书和私钥 在第一个示例中,keytool正在创建它们并将它们放入密钥库中 在第二个示例中,您缺少私钥。
你应该这样做:
将公共证书和私钥导入pkcs12(* .p12)密钥库
openssl pkcs12 -export -in mycert.crt -inkey mykey.key \
-out lig.p12 -name some-alias \
-CAfile ca.crt -caname root
将pkcs12转换为JSK
keytool -importkeystore \
-deststorepass changeit -destkeypass changeit -destkeystore lig.keystore \
-srckeystore lig.p12 -srcstoretype PKCS12 -srcstorepass some-password \
-alias some-alias
请从您的代码
参数说明
mycert.crt - &gt;你的公共证书
mykey.key - &gt;你的私钥
ca.crt - &gt;签署公共证书和私钥的证书颁发机构的公共证书
您 可以 不使用 ca.crt 来创建p12密钥库,但 应该 。 p12也可以用来保存它,如果它不存在,你可能有些库存在问题。无论如何,你可以尝试使用和不使用它;如果失败,图书馆很可能会非常清楚地告诉你这个问题
如果您使用的是自签名证书,那么您绝对可以忘记 ca.crt 参数,并且任何程序都不会给您带来任何问题。但是,如果我理解得很好,你使用的是第三方证书,所以我猜他们已经给了你ca.cert或者.p12包含了所有内容(或.pfx,它是相同的)。
如果它仍然不清楚,你可以列出他们提供给你的文件,我可以告诉你哪一个是哪个。我想系统管理员一致地命名文件(他们通常会这样做),所以它应该是非常直接的。