Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android SSL证书固定_Android_Ssl - Fatal编程技术网

Android SSL证书固定

Android SSL证书固定,android,ssl,Android,Ssl,我知道在安卓系统中有很多关于固定证书的问题,但我找不到我想要的 I子类化SSLSocketFactory并重写checkServerTrusted()方法。在此方法中,我执行以下操作: CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate ca = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(PUB_K

我知道在安卓系统中有很多关于固定证书的问题,但我找不到我想要的

I子类化
SSLSocketFactory
并重写
checkServerTrusted()
方法。在此方法中,我执行以下操作:

CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate ca = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(PUB_KEY.getBytes("UTF-8")));
for (X509Certificate cert : chain) {
    // Verifing by public key
    cert.verify(ca.getPublicKey());                      
}
链中的一个项目验证,另一个不验证(这会引发
异常
)。我想我无法掌握证书链是如何工作的


同一个公共证书是否应该验证链中的所有证书?

我发现在Android上实现证书固定的最简单方法是使用库

以下是一份:

默认情况下,OkHttp信任主机平台的证书颁发机构。此策略可最大化连接,但会受到证书颁发机构的攻击,例如。它还假定HTTPS服务器的证书由证书颁发机构签名

用于约束受信任的证书颁发机构。证书固定增加了安全性,但限制了服务器团队更新其TLS证书的能力未经服务器TLS管理员许可,请勿使用证书固定

如果您需要支持自签名证书,则的答案将指导您

同一公共证书是否应与中的所有证书进行验证 链子

答:没有

大多数公共CA不直接签署服务器证书。相反,它们使用其主CA证书(称为
根CA
)对中间CA进行签名。他们这样做是为了使根CA可以脱机存储,以减少泄露的风险。然而,像Android这样的操作系统通常直接
只信任根CA
,这在中间CA签署的服务器证书和知道根CA的证书验证器之间留下了很短的信任差距

要解决这个问题,服务器不发送客户端,只发送 SSL握手期间的证书,但来自的证书链 服务器可以通过任何必要的中介来访问受信任的服务器 根约

查看更多信息。希望这对用户有帮助

证书和公钥固定(也称为证书固定) 果壳-

通常,应用程序信任所有预安装的CA。如果这些CA中的任何一个颁发欺诈性证书,应用程序将面临中间人攻击(又称窃听)的风险。一些应用程序选择通过限制它们信任的CA集或通过证书固定来限制它们接受的证书集。证书固定是通过公钥散列提供一组证书来完成的。证书固定是一种依赖于客户端服务器证书验证的方法

下面是在Android上实现证书固定的3种方法-

  • 老派的方式-信任经理-

  • OkHttp证书颁发者-

  • 新鲜事-网络安全配置-


特别是对于您的问题,您可以通过使用
标记在NSC中散列公钥来配置证书

请注意,在使用证书固定时,应始终包含备份密钥,以便在强制切换到新密钥或更改CA(当固定到CA证书或该CA的中间证书时)时,应用程序的连接不会受到影响。否则,您必须推出应用程序更新以恢复连接


example.com
7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=
fwza0LRMXouZHRC8Ei+4YULDPDCF3UKGO/04cDM1oE=

查看Android使用的示例代码。您提到了一个
异常。有日志吗?你是否面临SSLHANDSHAKE例外?
  public CertificatePinning() {
    client = new OkHttpClient();
    client.setCertificatePinner(
        new CertificatePinner.Builder()
            .add("publicobject.com", "sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=")
            .add("publicobject.com", "sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=")
            .add("publicobject.com", "sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=")
            .add("publicobject.com", "sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=")
            .build());
  }

  public void run() throws Exception {
    Request request = new Request.Builder()
        .url("https://publicobject.com/robots.txt")
        .build();

    Response response = client.newCall(request).execute();
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

    for (Certificate certificate : response.handshake().peerCertificates()) {
      System.out.println(CertificatePinner.pin(certificate));
    }
  }
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <pin-set expiration="2018-01-01">
            <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
            <!-- backup pin -->
            <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>
        </pin-set>
    </domain-config>
</network-security-config>