2012-04-04 70 views
0

我试图用相同的密钥库连接客户端和服务器。 客户端套接字可以获得对等证书,而服务器套接字不能获得对等证书,但可以获得端口。 它无法获得证书并报告SSLPeerUnverifiedException异常。 修改问题困惑了我好几天了,请帮助解决它,谢谢SSLPeerUnverifiedException服务器中没有客户端证书

我的Android代码如下:

客户端:

java.security.Security.addProvider(
     new org.bouncycastle.jce.provider.BouncyCastleProvider()); 

SSLContext sslcontext = SSLContext.getInstance("TLS"); 
      sslcontext.init(getKeyManagers(), {new DummyTrustManager()}, null); 
SocketFactory socketFactory = sslcontext.getSocketFactory(); 

SSLSocket socket = (SSLSocket) socketFactory.createSocket("127.0.0.1", 8080); 
socket.getSession().getLocalCertificates(); 
socket.getSession().getPeerHost(); 
socket.getSession().getPeerPort(); 
socket.getSession().getPeerCertificates();` 

服务器:

SSLContext sslcontext = SSLContext.getInstance("TLS"); 
    sslcontext.init(getKeyManagers(), {new DummyTrustManager()}, null); 
ServerSocketFactory mFactory = sslcontext.getServerSocketFactory(); 
ServerSocket serverSocket =mFactory.createServerSocket(8080); 
SSLSocket clientSocket = serverSocket.accept(); 
socket.getSession().getLocalCertificates(); 
socket.getSession().getPeerHost(); 
socket.getSession().getPeerPort(); 
socket.getSession().getPeerCertificates();` 

的TrustManager:

import java.security.cert.X509Certificate; 
import javax.net.ssl.X509TrustManager; 
public class DummyTrustManager implements X509TrustManager { 
    public void checkClientTrusted(X509Certificate[] chain, String authType) { 
    // Does not throw CertificateException: all chains trusted 
    return; 
    } 
    public void checkServerTrusted(X509Certificate[] chain, String authType) { 
    // Does not throw CertificateException: all chains trusted 
    return; 
    } 
    public X509Certificate[] getAcceptedIssuers() { 
    return new X509Certificate[0]; 
    } 
} 

密钥库:

public void initializeKeyStore(String id) { 
try { 
    Log.v(LOG_TAG, "Generating key pair ..."); 
    KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); 
    KeyPair keyPair = kg.generateKeyPair(); 


    Log.v(LOG_TAG, "Generating certificate ..."); 
    String name = getCertificateName(id); 
    X509Certificate cert = SslUtil.generateX509V3Certificate(keyPair, name); 
    Certificate[] chain = {cert}; 


    Log.v(LOG_TAG, "Adding key to keystore ..."); 
    mKeyStore.setKeyEntry(
     LOCAL_IDENTITY_ALIAS, keyPair.getPrivate(), null, chain); 


    Log.d(LOG_TAG, "Key added!"); 
} catch (GeneralSecurityException e) { 
    throw new IllegalStateException("Unable to create identity KeyStore", e); 
} 
store(mKeyStore);} 




public synchronized KeyManager[] getKeyManagers() 
    throws GeneralSecurityException { 
if (mKeyStore == null) { 
    throw new NullPointerException("null mKeyStore"); 
} 
KeyManagerFactory factory = 
    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
factory.init(mKeyStore, "".toCharArray()); 
return factory.getKeyManagers(); 

}

证书:

public static X509Certificate generateX509V3Certificate(KeyPair pair, 
    String name) throws GeneralSecurityException { 
Calendar calendar = Calendar.getInstance(); 
calendar.set(2009, 0, 1); 
Date notBefore = new Date(calendar.getTimeInMillis()); 
calendar.set(2099, 0, 1); 
Date notAfter = new Date(calendar.getTimeInMillis()); 

BigInteger serialNumber = BigInteger.valueOf(Math.abs(
    System.currentTimeMillis())); 

return generateX509V3Certificate(pair, name, notBefore, notAfter, 
    serialNumber); 

}

public static X509Certificate generateX509V3Certificate(KeyPair pair, 
    String name, Date notBefore, Date notAfter, BigInteger serialNumber) 
    throws GeneralSecurityException { 
java.security.Security.addProvider(
    new org.bouncycastle.jce.provider.BouncyCastleProvider()); 
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); 
X509Name dnName = new X509Name(name); 

certGen.setSerialNumber(serialNumber); 
certGen.setIssuerDN(dnName); 
certGen.setSubjectDN(dnName); // note: same as issuer 
certGen.setNotBefore(notBefore); 
certGen.setNotAfter(notAfter); 
certGen.setPublicKey(pair.getPublic()); 
certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); 


certGen.addExtension(X509Extensions.BasicConstraints, true, 
    new BasicConstraints(false)); 

certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature 
    | KeyUsage.keyEncipherment | KeyUsage.keyCertSign)); 
certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(
    KeyPurposeId.id_kp_serverAuth)); 


AuthorityKeyIdentifier authIdentifier = createAuthorityKeyIdentifier(
    pair.getPublic(), dnName, serialNumber); 

certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, true, 
    authIdentifier); 
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, true, 
    new SubjectKeyIdentifierStructure(pair.getPublic())); 


certGen.addExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(
    new GeneralName(GeneralName.rfc822Name, "[email protected]"))); 


// This method is deprecated, but Android Eclair does not provide the 
// generate() methods. 
X509Certificate cert = certGen.generateX509Certificate(pair.getPrivate(), "BC"); 
return cert; 

}

enter code here 

回答

0

您可能需要拨打SSLServerSocket.setNeedClientAuth()让服务器端需要客户端身份验证。然后客户将发送其证书,并且您应该可以通过getPeerCertificates()获得。

参考:

http://docs.oracle.com/javase/6/docs/api/javax/net/ssl/SSLServerSocket.html#setNeedClientAuth%28boolean%29

+0

好吧,我会试试看。但我记得打电话给SSLServerSocket.setNeedClientAuth(),这并不好。 – user1312018 2012-04-04 08:17:08

+0

对不起,我来不及回复。它在android2.3和android 2.4中运行正常,而不是在android 2.2中运行。我跟踪它,发现openssl中可能有些问题。我该如何解决它。 – user1312018 2012-04-06 10:44:11

+0

如果它是固件中的错误,那么你不能。你为什么认为这是openssl的问题? – 2012-04-06 13:55:32

0

I'm trying to connect client and server with the same keystore

这只是一个有效的事情做的客户端实体和服务器实体实际上是同一个法人实体。

如果不是这样,那么您肯定会完全以错误的方式狂吠,这种方式具有非常深远的法律后果。我建议你在继续之前从商业/法律方面寻求建议。

相关问题