【问题标题】:SSLPeerUnverifiedException without client's cert in server服务器中没有客户端证书的 SSLPeerUnverifiedException
【发布时间】:2012-04-04 06:38:21
【问题描述】:

我正在尝试使用相同的 keystore 连接客户端和服务器。 客户端套接字可以获得对等证书,而服务器套接字无法获得对等证书但端口。 获取证书失败,报SSLPeerUnverifiedException异常。 修改后的问题困扰了我好几天,请帮忙解决,谢谢

我的安卓代码如下:

客户:

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

信任经理:

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, "googletv@test.test")));


// 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

【问题讨论】:

    标签: android ssl


    【解决方案1】:

    您可能需要调用SSLServerSocket.setNeedClientAuth() 以使服务器端要求客户端身份验证。然后客户端将发送其证书,您应该能够使用getPeerCertificates() 获取它。

    参考:

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

    【讨论】:

    • 好的,我会试试的。但是我记得调用SSLServerSocket.setNeedClientAuth(),不行。
    • 对不起,我来不及回复了。它在 android2.3 和 android 2.4 中运行良好,而不是在 android 2.2 中。我追踪了一下,发现可能是openssl出了点问题。我该如何解决它。
    • 如果是固件中的错误,你真的不能。为什么你认为这是 openssl 的问题?
    • stackoverflow.com/questions/9538714/…。我跟踪它并在文件 SSL_lib.c 中的函数 SSL_get_peer_cert_chain 中找到了这个词(如果我们是客户端,cert-chain 包括对等方自己的证书;如果我们是服务器,则没有。)。
    • 现在我得到了另一个例外。像这样。 stackoverflow.com/questions/9328699/….
    【解决方案2】:

    我正在尝试使用相同的密钥库连接客户端和服务器

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

    如果不是这样,那你肯定是完全找错了树,这会产生非常深远的法律后果。我建议您在继续之前咨询业务/法律方面的建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-05
      • 2021-09-03
      • 2015-10-20
      • 1970-01-01
      • 2012-03-28
      • 2021-10-03
      • 1970-01-01
      • 2014-05-31
      相关资源
      最近更新 更多