没有以前的internet连接,无法验证Android自签名证书
工作的SSL基础架构:没有以前的internet连接,无法验证Android自签名证书,android,ssl,https,certificate,self-signed,Android,Ssl,Https,Certificate,Self Signed,工作的SSL基础架构: //Using a client certificate String password = "clientpass"; KeyStore keyStore = KeyStore.getInstance("PKCS12"); InputStream is = context.getResources().openRawResource(R.raw.client); keyStore.load(is, password.toCharA
//Using a client certificate
String password = "clientpass";
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream is = context.getResources().openRawResource(R.raw.client);
keyStore.load(is, password.toCharArray());
is.close();
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, password.toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
// Using self signed certificate
CertificateFactory cf = CertificateFactory.getInstance("X.509");
is = context.getResources().openRawResource(R.raw.cacert);
InputStream caInput = new BufferedInputStream(is);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.i("CA","ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
// Create an SSLContext that uses our Trustmanager and Keymanager
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keyManagers, trustManagers, null);
//create a socket to connect with the server
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket(serverAddr, port);
socket.setUseClientMode(true);
socket.addHandshakeCompletedListener(this);
socket.startHandshake();
javax.net.ssl.SSLHandshakeException: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: null
我们有一个有效的客户机/服务器设置,Android版本为4.2和4.4的手机充当客户机,必须通过自签名SSL证书验证服务器
问题:
//Using a client certificate
String password = "clientpass";
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream is = context.getResources().openRawResource(R.raw.client);
keyStore.load(is, password.toCharArray());
is.close();
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, password.toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
// Using self signed certificate
CertificateFactory cf = CertificateFactory.getInstance("X.509");
is = context.getResources().openRawResource(R.raw.cacert);
InputStream caInput = new BufferedInputStream(is);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.i("CA","ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
// Create an SSLContext that uses our Trustmanager and Keymanager
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keyManagers, trustManagers, null);
//create a socket to connect with the server
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket(serverAddr, port);
socket.setUseClientMode(true);
socket.addHandshakeCompletedListener(this);
socket.startHandshake();
javax.net.ssl.SSLHandshakeException: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: null
只要设备在尝试连接之前至少访问过一次internet,服务器证书验证就可以工作。但是,如果执行出厂重置,并且设备直接连接到专用网络而没有internet连接,则证书验证失败
要复制该行为,请执行以下操作:
//Using a client certificate
String password = "clientpass";
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream is = context.getResources().openRawResource(R.raw.client);
keyStore.load(is, password.toCharArray());
is.close();
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, password.toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
// Using self signed certificate
CertificateFactory cf = CertificateFactory.getInstance("X.509");
is = context.getResources().openRawResource(R.raw.cacert);
InputStream caInput = new BufferedInputStream(is);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.i("CA","ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
// Create an SSLContext that uses our Trustmanager and Keymanager
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keyManagers, trustManagers, null);
//create a socket to connect with the server
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket(serverAddr, port);
socket.setUseClientMode(true);
socket.addHandshakeCompletedListener(this);
socket.startHandshake();
javax.net.ssl.SSLHandshakeException: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: null
失败,startHandshake中出现异常:
//Using a client certificate
String password = "clientpass";
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream is = context.getResources().openRawResource(R.raw.client);
keyStore.load(is, password.toCharArray());
is.close();
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, password.toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
// Using self signed certificate
CertificateFactory cf = CertificateFactory.getInstance("X.509");
is = context.getResources().openRawResource(R.raw.cacert);
InputStream caInput = new BufferedInputStream(is);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.i("CA","ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
// Create an SSLContext that uses our Trustmanager and Keymanager
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keyManagers, trustManagers, null);
//create a socket to connect with the server
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket(serverAddr, port);
socket.setUseClientMode(true);
socket.addHandshakeCompletedListener(this);
socket.startHandshake();
javax.net.ssl.SSLHandshakeException: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: null
确保设备上的时间正确,证书具有有效期,并且如果将日期设置为过去(通常是工厂重置后的2000年1月1日)或未来,证书将不会生效。该设备将通过NTP自动同步,但当没有可用的Internet连接时,这显然不起作用 您对HTTP请求使用什么<代码>网络视图<代码>HttpUrlConnection<代码>确定http<代码>HttpClient?还有什么吗?我正在构建自己的SSLContext来创建具有特定信任库和密钥库的SSLSockets。如果跳过第2步和第3步,第一次尝试是否有效?您看,您确定这不是首次使用失败,而是没有互联网接入失败吗?您的具体测试设备是什么?您是否能够在SDK的模拟器上重现此问题(在仅连接到专用网络的开发机器上运行)?如果我在连接到专用服务器之前访问过一次internet,它可以正常工作,但您的设备上的时间对吗?查看
RFC3280CertPathUtilities.java
,此消息仅针对过期/尚未生效的证书生成。如果您没有Internet,设备无法与NTP同步时间,因此很可能日期设置为2000年或类似的日期。很好的发现。该死,我已经被它咬了很多次了,我都数不清。。。但通常是通过蜂窝无线电(无Wifi/BT)。我很惊讶它没有向我扑来。