如何在 Flutter 中进行 public 键固定?

How can I do public key pinning in Flutter?

我想固定我服务器的 public 密钥,以便对服务器发出的任何请求都必须具有该 public 密钥(这是为了防止像 Charles 这样的代理嗅探数据) .

我在 Android 中用 Volley 做了类似的事情。

我怎样才能用 Flutter 做同样的事情?

使用没有可信根的 SecurityContext 创建您的客户端以强制执行错误的证书回调,即使是好的证书也是如此。

SecurityContext(withTrustedRoots: false);

在错误证书回调中,使用asn1lib package解析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;

ASN1BitString pubKeyBits = pubKeyElement.elements[1] as ASN1BitString;

List<int> encodedPubKey = pubKeyBits.stringValue;
// could stop here and compare the encoded key parts, or...

// parse them into their modulus/exponent parts, and test those
// (assumes RSA public key)
ASN1Parser rsaParser = ASN1Parser(encodedPubKey);
ASN1Sequence keySeq = rsaParser.nextObject() as ASN1Sequence;
ASN1Integer modulus = keySeq.elements[0] as ASN1Integer;
ASN1Integer exponent = keySeq.elements[1] as ASN1Integer;

print(modulus.valueAsBigInteger);
print(exponent);

密钥轮换降低了风险。当攻击者获得旧服务器硬盘驱动器或备份文件并从中获取旧服务器私钥时,如果密钥已轮换,则他们无法冒充当前服务器。因此,在更新证书时总是生成一个新密钥。配置客户端以信任旧密钥和新密钥。等待您的用户更新到新版本的客户端。然后将新密钥部署到您的服务器。然后你可以从客户端删除旧密钥。

只有在不轮换密钥时才需要固定服务器密钥。这是糟糕的安全做法。

您应该轮换固定证书。我在 How to do SSL pinning via self generated signed certificates in flutter? 中添加了示例代码?