菜鸟教程小白 发表于 2022-12-12 23:53:47

android - 无法从 Android 链中获取根 CA 证书


                                            <p><p>我想做的事情非常简单——我想在从 iOS 和 Android 应用程序连接到服务器时获得完整的证书链。</p>

<p>在 iOS 中,我正在使用 <code>NSURLSession</code> 并重写 <code>URLSession:didReceiveChallenge:</code> 方法,在这种情况下我可以获得证书链,在这种情况下看起来像预期的那样:</p>

<p><code>
[叶证书] - [中间证书] - [根证书]
</code></p>

<p>可爱。</p>

<p>现在我正尝试在 Android 设备上使用 <code>HttpsURLConnection</code> 做同样的事情。连接到服务器后,我使用 <code>getServerCertificates()</code> 方法获取证书链(或者至少我希望这是它的方法)。这将返回我的 <code>Certificate[]</code> 对象,我在其中获得如下所示的链:</p>

<p><code>
【叶证书】-【中级证书】
</code></p>

<p>因此,Android 设备上没有根证书。</p>

<p>你知道Android中如何从链上获取根证书吗?</p>

<p>提前谢谢你。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>你的问题看起来很简单。我正在查看 TLS 规范中的服务器证书部分。看这个<a href="https://security.stackexchange.com/questions/93157/in-ssl-server-handshake-does-server-also-send-ca-certificate" rel="noreferrer noopener nofollow">post</a> </p>

<p><strong>服务器必须发送排序者证书链</strong>,以服务器证书和中间件开始<strong>但 CA 根是可选的</strong>,因为标准要求根证书独立分发.服务器不包含 CA 根是很常见的</p>

<p>客户端验证在信任库中寻找根 CA 的链。验证由 <a href="https://developer.android.com/reference/javax/net/ssl/X509TrustManager.html" rel="noreferrer noopener nofollow">X509TrustManager</a> 执行返回找到的根证书是可取的,但是,如您所见,负责验证的方法静默完成</p>

<pre><code> public void checkServerTrusted(X509Certificate[] chain, String authType)
</code></pre>

<p><strong>已编辑 - 如何从 HTTPS 连接获取可信根</strong></p>

<p>您可以使用可用的受信任证书列表来验证中间证书,以检查其中哪一个是颁发者。 (从 <a href="https://stackoverflow.com/questions/13742028/overriding-the-ssl-trust-manager-in-android" rel="noreferrer noopener nofollow">here</a> 和 <a href="https://stackoverflow.com/a/8694377/6371459" rel="noreferrer noopener nofollow">here</a> 中提取的代码 </p>

<pre><code>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;

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

for (int i = 0; i &lt; issuers.length;i++){
    try{
      intermediate.verify(issuers.getPublicKey());
            //Verification ok. issuers is the issuer
            return issuers;
      } catch (Exception e){}
    }
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于android - 无法从 Android 链中获取根 CA 证书,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/42161851/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/42161851/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: android - 无法从 Android 链中获取根 CA 证书