无法从 Android 中的链获取根 CA 证书
Can't get root CA certificate from the chain in Android
我想做的事情非常简单 - 我想在从 iOS 和 Android 应用程序连接到服务器时获得完整的证书链。
在 iOS 中,我正在使用 NSURLSession
并覆盖 URLSession:didReceiveChallenge:
方法,在该方法中我可以获得证书链,在这种情况下看起来像预期的那样:
[leaf certificate] - [intermediate certificate] - [root certificate]
可爱。
现在我正尝试在 Android 设备上使用 HttpsURLConnection
做同样的事情。连接到服务器后,我使用 getServerCertificates()
方法获取证书链(或者至少我希望这是它的方法)。这个 returns 我 Certificate[]
对象,我在其中得到如下所示的链:
[leaf certificate] - [intermediate certificate]
因此,Android 设备上没有根证书。
你知道如何从Android中的链获取根证书吗?
提前谢谢你。
你的问题看起来很简单。我正在查看 TLS 规范中的服务器证书部分。看到这个 post
服务器必须发送一个订购者证书链以服务器证书和中间件开始但 CA 根是可选的,因为根证书独立分发的标准。服务器不包含 CA root
是很常见的
客户端验证在信任库中寻找根 CA 的链。验证由 X509TrustManager 执行 return 找到根证书是可取的,但是,如您所见,负责验证的方法静默完成
public void checkServerTrusted(X509Certificate[] chain, String authType)
已编辑 - 如何从 HTTPS 连接获取受信任的根目录
您可以使用可用的受信任证书列表来验证中间证书,以检查其中哪一个是颁发者。 (从 here and here
中提取的代码
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
// Initialise the TMF as you normally would, for example:
tmf.init((KeyStore)null);
//get default X509TrustManager
TrustManager[] trustManagers = tmf.getTrustManagers();
final X509TrustManager x509Tm = (X509TrustManager)trustManagers[0];
//trusted certificate issuers
X509Certificate issuers[] = x509Tm.getAcceptedIssuers();
//Perform connection...
HttpsURLConnection conn =....
//get the last intermediate certificate from server certificates.
//Fixme: if the server returns alsothe root certificate...
Certificate cert[] = conn.getServerCertificates();
X509Certificate intermediate = (X509Certificate)cert[cert.length-1];
for (int i = 0; i < issuers.length;i++){
try{
intermediate.verify(issuers[i].getPublicKey());
//Verification ok. issuers[i] is the issuer
return issuers[i];
} catch (Exception e){}
}
}
我想做的事情非常简单 - 我想在从 iOS 和 Android 应用程序连接到服务器时获得完整的证书链。
在 iOS 中,我正在使用 NSURLSession
并覆盖 URLSession:didReceiveChallenge:
方法,在该方法中我可以获得证书链,在这种情况下看起来像预期的那样:
[leaf certificate] - [intermediate certificate] - [root certificate]
可爱。
现在我正尝试在 Android 设备上使用 HttpsURLConnection
做同样的事情。连接到服务器后,我使用 getServerCertificates()
方法获取证书链(或者至少我希望这是它的方法)。这个 returns 我 Certificate[]
对象,我在其中得到如下所示的链:
[leaf certificate] - [intermediate certificate]
因此,Android 设备上没有根证书。
你知道如何从Android中的链获取根证书吗?
提前谢谢你。
你的问题看起来很简单。我正在查看 TLS 规范中的服务器证书部分。看到这个 post
服务器必须发送一个订购者证书链以服务器证书和中间件开始但 CA 根是可选的,因为根证书独立分发的标准。服务器不包含 CA root
是很常见的客户端验证在信任库中寻找根 CA 的链。验证由 X509TrustManager 执行 return 找到根证书是可取的,但是,如您所见,负责验证的方法静默完成
public void checkServerTrusted(X509Certificate[] chain, String authType)
已编辑 - 如何从 HTTPS 连接获取受信任的根目录
您可以使用可用的受信任证书列表来验证中间证书,以检查其中哪一个是颁发者。 (从 here and here
中提取的代码TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
// Initialise the TMF as you normally would, for example:
tmf.init((KeyStore)null);
//get default X509TrustManager
TrustManager[] trustManagers = tmf.getTrustManagers();
final X509TrustManager x509Tm = (X509TrustManager)trustManagers[0];
//trusted certificate issuers
X509Certificate issuers[] = x509Tm.getAcceptedIssuers();
//Perform connection...
HttpsURLConnection conn =....
//get the last intermediate certificate from server certificates.
//Fixme: if the server returns alsothe root certificate...
Certificate cert[] = conn.getServerCertificates();
X509Certificate intermediate = (X509Certificate)cert[cert.length-1];
for (int i = 0; i < issuers.length;i++){
try{
intermediate.verify(issuers[i].getPublicKey());
//Verification ok. issuers[i] is the issuer
return issuers[i];
} catch (Exception e){}
}
}