我遇到了使用this method来解决使用HttpClient 4遇到的“javax.net.ssl.SSLPeerUnverifiedException:No peer certificate”异常的问题。但是,这导致了以下javax.net.ssl .SSLHandshakeException:java.security.cert.CertPathValidatorException:
System.err W javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Intermediate certificate lacks BasicCon
straints
System.err W at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:477)
System.err W at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.<init>(OpenSSLSocketImpl.java:750)
System.err W at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:692)
System.err W at org.apache.http.impl.io.SocketInputBuffer.<init>(SocketInputBuffer.java:93)
System.err W at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83)
System.err W at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170)
System.err W at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106)
System.err W at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129)
System.err W at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:171)
System.err W at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
System.err W at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
System.err W at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
System.err W at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
System.err W at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
System.err W at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
System.err W at com.example.activities.AuthTest.onCreate(AuthTest.java:69)
System.err W at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
System.err W at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722)
System.err W at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
System.err W at android.app.ActivityThread.access$1500(ActivityThread.java:123)
System.err W at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
System.err W at android.os.Handler.dispatchMessage(Handler.java:99)
System.err W at android.os.Looper.loop(Looper.java:130)
System.err W at android.app.ActivityThread.main(ActivityThread.java:3835)
System.err W at java.lang.reflect.Method.invokeNative(Native Method)
System.err W at java.lang.reflect.Method.invoke(Method.java:507)
System.err W at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
System.err W at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
System.err W at dalvik.system.NativeStart.main(Native Method)
System.err W Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Intermediate certificate
lacks BasicConstraints
System.err W at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:161)
System.err W at com.example.models.EasyX509TrustManager.checkServerTrusted(EasyX509TrustManager.java:80)
System.err W at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:664)
System.err W at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
System.err W at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:474)
System.err W ... 28 more
System.err W Caused by: java.security.cert.CertPathValidatorException: Intermediate certificate lacks BasicConstraints
System.err W at org.bouncycastle.jce.provider.RFC3280CertPathUtilities.prepareNextCertK(RFC3280CertPathUtilities.java:2127)
System.err W at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:384)
System.err W at java.security.cert.CertPathValidator.validate(CertPathValidator.java:197)
System.err W at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:156)
System.err W ... 32 more
我通过注释掉EasyX509TrustManager.java中的以下else块来解决 :
public void checkServerTrusted( X509Certificate[] certificates, String authType )
throws CertificateException
{
if ( ( certificates != null ) && ( certificates.length == 1 ) )
{
certificates[0].checkValidity();
}
//else
//{
// standardTrustManager.checkServerTrusted( certificates, authType );
//}
}
Voila!一切正常。问题是我真的不知道“中间证书缺少BasicCosntraints”异常意味着什么,或者如果注释掉else块会引入安全风险,我可能会信任无效证书。
原始的SSLPeerUnverifiedException在Android 2.1或2.2上都没有出现,所以这似乎只是Android 2.3 +上的一个问题。
有人可以帮我理解这个例外究竟意味着什么吗?如果这是一个安全风险,我将如何开始解决这个问题?
答案 0 :(得分:1)
基本约束指定证书是否可以颁发其他证书(是证书颁发机构;技术上可以使其公钥签署其他证书),以及它颁发的证书是否可以依次颁发其他证书(链长可以是谁)。因此,如果有人伪造它,您可以使用/信任由不应该首先颁发证书的人颁发的证书。评论checkServerTrusted
错误:你基本上是在说:我不关心这是谁的证书,只要它没有破坏而且没有过期。这种方式失败了,因为任何人都可以签发有效证书。
可能2.1和2.2不关心检查约束,2.3开始,这就是你得到错误的原因。你可以发布这些证书的链接吗?
所有血腥细节都在RFC 3280。