Android 2.3:HttpClient SSL 证书问题:中间证书缺少 BasicConstraints
我在使用此方法来解决“使用 HttpClient 4 遇到 javax.net.ssl.SSLPeerUnverifiedException:无对等证书”异常。但是,这导致了以下问题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 );
//}
}
瞧! 并且一切都按其应有的方式进行。问题是我真的不知道“中间证书缺少 BasicCosntraints”异常意味着什么,或者注释掉 else 块是否会带来安全风险,我可能会信任无效的证书。
最初的 SSLPeerUnverifiedException 在 Android 2.1 或 2.2 上都没有发生,因此这似乎只是 Android 2.3+ 上的问题。
有人可以帮我理解这个异常到底意味着什么吗?如果这是一个安全风险,我将如何开始解决这个问题?
I'm running into a problem using this method to address a "javax.net.ssl.SSLPeerUnverifiedException: No peer certificate" exception encountered using HttpClient 4. This, however, caused the following 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
I got around that by commenting out the following else block found in EasyX509TrustManager.java:
public void checkServerTrusted( X509Certificate[] certificates, String authType )
throws CertificateException
{
if ( ( certificates != null ) && ( certificates.length == 1 ) )
{
certificates[0].checkValidity();
}
//else
//{
// standardTrustManager.checkServerTrusted( certificates, authType );
//}
}
Voila! And everything works as it should. The problem is that I really have no idea what the "Intermediate certificate lacks BasicCosntraints" exception means or if commenting out that else block introduces a security risk where I may be trusting invalid certificates.
The original SSLPeerUnverifiedException did not occur on either Android 2.1 or 2.2, so this seems to be just a problem on Android 2.3+.
Could someone please help me understand what exactly that exception means? And if this is a security risk, how would I begin to go about resolving this issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基本约束指定一个证书是否可以颁发其他证书(它是证书颁发机构吗?从技术上讲,它的公钥可以签署其他证书),以及它颁发的证书是否可以依次颁发其他证书(链长的人可以)。因此,如果有人伪造它,您可能会被迫使用/信任由本来不应该颁发证书的人颁发的证书。注释掉
checkServerTrusted
是坏:你基本上是在说:我不在乎这是谁的证书,只要它没有损坏并且没有过期。这违背了目的,因为任何人都可以颁发有效的证书。可能 2.1 和 2.2 不关心检查约束,而 2.3 开始关心,这就是您收到错误的原因。您可以发布这些证书的链接吗?
所有血淋淋的细节都在 RFC 3280 中。
Basic constraints specify whether a certificate can issue other certificates (is it Certificate Authority; technically can its public key sign other certificates), and whether the certificates it issued can in turn issue other certificates (who long the chain can be). So if some one fakes it, you can be made to use/trust a certificate issued by someone who is not supposed to issue certificates in the first place. Commenting out
checkServerTrusted
is bad: you are basically saying: I don't care whose certificate this is, as long as it's not broken and not expired. This kind of defeats the purpose, because anyone can issue a valid certificate.Possibly 2.1 and 2.2 didn't care about checking constraints and 2.3 started to and that is why you are getting an error. Can you post a link to those certificates?
All the gory details are in RFC 3280.