getCipherSuite()返回SSL_NULL_WITH_NULL_NULL [英] getCipherSuite() returns SSL_NULL_WITH_NULL_NULL
问题描述
我试图让Android上的HTTPS服务器以编程方式生成的自签名证书。我觉得我pretty接近,但我仍然无法连接到HTTPS服务器。当我尝试与OpenSSL的连接到服务器,我得到以下内容:
的OpenSSL的s_client.First -connect 192.168.1.97:8888
CONNECTED(00000003)
2895:错误:14077410:SSL例程:SSL23_GET_SERVER_HELLO:SSLv3的警报握手失败:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s23_clnt.c:602:
在code是以下内容:
公共类HttpsHello {
私人静态字符串则domainName =localhost的; 静态的 {
Security.addProvider(新BouncyCastleProvider());
} 公共静态无效测试(字串[] args){ 尝试{
的KeyPairGenerator KeyPairGenerator的= KeyPairGenerator.getInstance(RSA);
keyPairGenerator.initialize(1024);
密钥对KPair = keyPairGenerator.generateKeyPair(); X509V3CertificateGenerator v3CertGen =新X509V3CertificateGenerator(); 。INT跑=新的SecureRandom()nextInt();
如果(RAN℃,)跑=跑* -1; 的BigInteger的serialNumber = BigInteger.valueOf(RAN); v3CertGen.setSerialNumber(的serialNumber);
v3CertGen.setIssuerDN(新X509Principal(CN =+则domainName +,OU =无,O =无L =无,C =无));
v3CertGen.setNotBefore(新的Date(System.currentTimeMillis的() - 1000L * 60 * 60 * 24 * 30));
v3CertGen.setNotAfter(新的Date(System.currentTimeMillis的()+(1000L * 60 * 60 * 24 * 365 * 10)));
v3CertGen.setSubjectDN(新X509Principal(CN =+则domainName +,OU =无,O =无L =无,C =无));
v3CertGen.setPublicKey(KPair.getPublic());
// v3CertGen.setSignatureAlgorithm(MD5WithRSAEncryption); v3CertGen.setSignatureAlgorithm(SHA1WithRSAEncryption); x509证书pkcert = v3CertGen.generateX509Certificate(KPair.getPrivate());
// FileOutputStream中FOS =新的FileOutputStream(/路径/要/ testCert.cert);
// fos.write(pkcert.getEn codeD());
// fos.close(); ByteArrayInputStream的证书=新ByteArrayInputStream进行(pkcert.getEn codeD()); 密钥库KS = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(NULL);
ks.setCertificateEntry(localhost,则pkcert); // ks.load(CERT,NULL);
KMF的KeyManagerFactory =
KeyManagerFactory.getInstance(X509);
kmf.init(KS,NULL); 的SSLContext SC = SSLContext.getInstance(TLS);
sc.init(kmf.getKeyManagers(),NULL,NULL);
SSF的SSLServerSocketFactory = sc.getServerSocketFactory(); SSLServerSocket小号
=(SSLServerSocket)ssf.createServerSocket(8888);
s.setEnabledCipherSuites(s.getSupportedCipherSuites());
// s.setEnabledCipherSuites(新的String [] {SSL_DH_anon_WITH_RC4_128_MD5});
// s.setEnabledCipherSuites(新的String [] {SHA1WithRSAEncryption});
的System.out.println(服务器开始:);
printServerSocketInfo(多个);
//侦听的端口
SSLSocket的C =(SSLSocket的)s.accept();
printSocketInfo(C);
BufferedWriter将W =新的BufferedWriter(
新OutputStreamWriter(c.getOutputStream()));
BufferedReader中R =新的BufferedReader(
新的InputStreamReader(c.getInputStream()));
串m = r.readLine();
w.write(HTTP / 1.0 200 OK);
w.newLine();
w.write(内容类型:text / html的);
w.newLine();
w.newLine();
w.write(< HTML和GT;<身体GT;世界,你好<!/身体GT;< / HTML>中);
w.newLine();
w.flush();
w.close();
r.close();
c.close();
}赶上(例外五){
e.printStackTrace();
}
} 私有静态无效printSocketInfo(的SSLSocket S){
的System.out.println(Socket类:+ s.getClass());
的System.out.println(远程地址=
+ s.getInetAddress()的toString());
的System.out.println(远程端口=+ s.getPort());
的System.out.println(本地套接字地址=
+ s.getLocalSocketAddress()的toString());
的System.out.println(本地地址=
+ s.getLocalAddress()的toString());
的System.out.println(本地端口=+ s.getLocalPort());
的System.out.println(需要客户端身份验证=
+ s.getNeedClientAuth());
的SSLSession SS = s.getSession();
的System.out.println(密码套件=+ ss.getCipherSuite());
的System.out.println(协议=+ ss.getProtocol());
} 私有静态无效printServerSocketInfo(SSLServerSocket S){
的System.out.println(服务器套接字类:+ s.getClass());
的System.out.println(Socker地址=
+ s.getInetAddress()的toString());
的System.out.println(Socker端口=
+ s.getLocalPort());
的System.out.println(需要客户端身份验证=
+ s.getNeedClientAuth());
的System.out.println(想客户端身份验证=
+ s.getWantClientAuth());
的System.out.println(使用客户端模式=
+ s.getUseClientMode());
}
}
感谢您。
编辑:我看了两个密钥工具生成的密钥库,其中一个工作,一个没有。一个密钥库工作在那里以PrivateKeyEntry作为的地方不工作之一具有trustedCertEntry一个条目。然后,我改变了这个code打印出的localhost的别名的条目,下面是我得到了什么,我猜问题是,它是一个受信任的证书项,而不是一个私钥项。我要如何改变这种状况?
信任的证书项:
[0]版本:3
的SerialNumber:752445443
IssuerDN:CN =本地主机,OU =无,O =无L,C =无
开始日期:星期一5月26日9时17分01秒2014年CDT
截止日期:星期六6月22日9时17分01秒CDT 2024
subjectDN中:CN =本地主机,OU =无,O =无L,C =无
公钥RSA公钥
模量: b75870cd29db79f8c015d440a27cc1e81c9dd829268efa2ce48efc596b33e9c60e1d1621e10aba34472b6f7890b16392db021c0358e665b1bf58a426fbc47e7c135da583e4cd6bb9c69668ee4ff1e05b1de8e7f5fb5604044a1087ac0181ba09f61ab5345d9be5d930889b7c328329d0d18cf53f4c5af6bff1f0e488744ea1fb
公用指数:10001
签名算法:SHA1WITHRSA
签名:83df0e761e9df2e61d5354ca58379975e0d97fcd
5201f8904b695d7bdbe08c5dfdfb8bcd6447657c
19740797a66314b2547a45985166c11ebadc16c6
c24b8e1d3c5de83ec1ac2c1c1092c3d06ed33408
4cf2811c5f9dba8a9d3ef0dcb8fef760e4d1d704
8fbb60eaa83eec23426fb9d8589e859a21a5ecce
951901f8e16ab6cd
s.setEnabledCipherSuites(s.getSupportedCipherSuites());
删除此行。
I'm trying to make an https server on Android with a programmatically generated self signed certificate. I feel like I'm pretty close but I still can't connect to the https server. When I attempt to connect to the server with openssl I get the following:
openssl s_client -connect 192.168.1.97:8888
CONNECTED(00000003)
2895:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s23_clnt.c:602:
The code is the following:
public class HttpsHello {
private static String domainName = "localhost";
static {
Security.addProvider(new BouncyCastleProvider());
}
public static void test(String[] args) {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair KPair = keyPairGenerator.generateKeyPair();
X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
int ran = new SecureRandom().nextInt();
if (ran < 0) ran = ran * -1;
BigInteger serialNumber = BigInteger.valueOf(ran);
v3CertGen.setSerialNumber(serialNumber);
v3CertGen.setIssuerDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));
v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30));
v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365 * 10)));
v3CertGen.setSubjectDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));
v3CertGen.setPublicKey(KPair.getPublic());
// v3CertGen.setSignatureAlgorithm("MD5WithRSAEncryption");
v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption");
X509Certificate pkcert = v3CertGen.generateX509Certificate(KPair.getPrivate());
// FileOutputStream fos = new FileOutputStream("/path/to/testCert.cert");
// fos.write(pkcert.getEncoded());
// fos.close();
ByteArrayInputStream cert = new ByteArrayInputStream(pkcert.getEncoded());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null);
ks.setCertificateEntry("localhost", pkcert);
// ks.load(cert,null);
KeyManagerFactory kmf =
KeyManagerFactory.getInstance("X509");
kmf.init(ks, null);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s
= (SSLServerSocket) ssf.createServerSocket(8888);
s.setEnabledCipherSuites(s.getSupportedCipherSuites());
// s.setEnabledCipherSuites(new String[]{"SSL_DH_anon_WITH_RC4_128_MD5"});
// s.setEnabledCipherSuites(new String[]{"SHA1WithRSAEncryption"});
System.out.println("Server started:");
printServerSocketInfo(s);
// Listening to the port
SSLSocket c = (SSLSocket) s.accept();
printSocketInfo(c);
BufferedWriter w = new BufferedWriter(
new OutputStreamWriter(c.getOutputStream()));
BufferedReader r = new BufferedReader(
new InputStreamReader(c.getInputStream()));
String m = r.readLine();
w.write("HTTP/1.0 200 OK");
w.newLine();
w.write("Content-Type: text/html");
w.newLine();
w.newLine();
w.write("<html><body>Hello world!</body></html>");
w.newLine();
w.flush();
w.close();
r.close();
c.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void printSocketInfo(SSLSocket s) {
System.out.println("Socket class: " + s.getClass());
System.out.println(" Remote address = "
+ s.getInetAddress().toString());
System.out.println(" Remote port = " + s.getPort());
System.out.println(" Local socket address = "
+ s.getLocalSocketAddress().toString());
System.out.println(" Local address = "
+ s.getLocalAddress().toString());
System.out.println(" Local port = " + s.getLocalPort());
System.out.println(" Need client authentication = "
+ s.getNeedClientAuth());
SSLSession ss = s.getSession();
System.out.println(" Cipher suite = " + ss.getCipherSuite());
System.out.println(" Protocol = " + ss.getProtocol());
}
private static void printServerSocketInfo(SSLServerSocket s) {
System.out.println("Server socket class: " + s.getClass());
System.out.println(" Socker address = "
+ s.getInetAddress().toString());
System.out.println(" Socker port = "
+ s.getLocalPort());
System.out.println(" Need client authentication = "
+ s.getNeedClientAuth());
System.out.println(" Want client authentication = "
+ s.getWantClientAuth());
System.out.println(" Use client mode = "
+ s.getUseClientMode());
}
}
Thank you.
EDIT: I looked at two keytool generated keystores, one which worked and one that didn't. The one keystore which works has an entry in there for a PrivateKeyEntry where as the one which doesn't work has a trustedCertEntry. I then changed this code to print out the entry for the "localhost" alias and below is what I got, I'm guessing the issue is that it is a Trusted certificate entry and not a private key entry. How do I change that?
Trusted certificate entry: [0] Version: 3 SerialNumber: 752445443 IssuerDN: CN=localhost,OU=None,O=None L,C=None Start Date: Mon May 26 09:17:01 CDT 2014 Final Date: Sat Jun 22 09:17:01 CDT 2024 SubjectDN: CN=localhost,OU=None,O=None L,C=None Public Key: RSA Public Key modulus: b75870cd29db79f8c015d440a27cc1e81c9dd829268efa2ce48efc596b33e9c60e1d1621e10aba34472b6f7890b16392db021c0358e665b1bf58a426fbc47e7c135da583e4cd6bb9c69668ee4ff1e05b1de8e7f5fb5604044a1087ac0181ba09f61ab5345d9be5d930889b7c328329d0d18cf53f4c5af6bff1f0e488744ea1fb public exponent: 10001 Signature Algorithm: SHA1WITHRSA Signature: 83df0e761e9df2e61d5354ca58379975e0d97fcd 5201f8904b695d7bdbe08c5dfdfb8bcd6447657c 19740797a66314b2547a45985166c11ebadc16c6 c24b8e1d3c5de83ec1ac2c1c1092c3d06ed33408 4cf2811c5f9dba8a9d3ef0dcb8fef760e4d1d704 8fbb60eaa83eec23426fb9d8589e859a21a5ecce 951901f8e16ab6cd
s.setEnabledCipherSuites(s.getSupportedCipherSuites());
Remove this line.
这篇关于getCipherSuite()返回SSL_NULL_WITH_NULL_NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!