2

Flutter 在这里相对较新(和一般编程)。只熟悉更基本的东西,但我现在遇到了在flutter/dart中使用CertificatePinner的需要: https ://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html (我已经在我之前在 android studio 的 kotlin/java 项目中成功实现了这一点)。我的目标是固定公钥(不是证书)

我所拥有的只是字符串形式的公钥,如下所示,仅此而已"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="

我该如何实现这一目标?我已经在 github 上的一个未解决问题中提出了这个问题,但还没有得到任何回复(https://github.com/dart-lang/sdk/issues/35981)。希望有人能够做到这一点。

我还搜索了其他来源。我认为最接近我的解决方案是如何在 Flutter 中进行公钥固定? 但我不太了解那里正在做什么,由于我还没有足够的声誉,因此我无法评论那里提出问题。

作为比较,我想要做的就是在flutter/dart中实现与我在java/kotlin中可以通过这几行代码相同的事情:

 String hostname = "publicobject.com";
 CertificatePinner certificatePinner = new CertificatePinner.Builder()
     .add(hostname, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
     .build();

谢谢你的帮助

4

1 回答 1

1

从您引用的答案中的代码开始。这将获取 DER 格式的证书并开始对其进行解码。

ASN1Parser p = ASN1Parser(der);
ASN1Sequence signedCert = p.nextObject() as ASN1Sequence;
ASN1Sequence cert = signedCert.elements[0] as ASN1Sequence;
ASN1Sequence pubKeyElement = cert.elements[6] as ASN1Sequence;
// this is the Subject Public Key element, which describes the type of key and actual value

例如,如果我们对 的证书进行解码,pub.dev我们发现它是一个模数为 65537,值为 2347 的 RSA 密钥……:

SEQUENCE (2 elem)
  SEQUENCE (2 elem)
    OBJECT IDENTIFIER 1.2.840.113549.1.1.1 rsaEncryption (PKCS #1)
    NULL
  BIT STRING (1 elem)
    SEQUENCE (2 elem)
      INTEGER (2048 bit) 234782553149463204049153749736864715384123240676730175743244004248041…
      INTEGER 65537

RFC来看,SPKI 指纹是整个元素的 SHA-256 哈希。

// you need to import dart:convert and package:crypto/crypto.dart
var hash = base64.encode(sha256.convert(pubKeyElement.contentBytes()).bytes);
var spkiFingerprint = 'sha256/$hash'; // should match the value you have

注意事项

badCertificateCallback不提供整个证书链,所以你不能走上整个链。更糟糕的是,它似乎并不总是提供叶子证书!有时它会提供中间证书。

于 2019-12-05T16:58:56.293 回答