错误信息
System.Security.Cryptography.CryptographicException: ASN1 corrupted data.
也可能输出为
- ASN1 corrupted data.
- Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: ASN1 corrupted data.
在 Linux 和 macOS 上,异常类型是 `CryptographicException`;在 Windows 上,它可能以 `WindowsCryptographicException` 出现,文本相同。内部异常的内容例如:“The provided data is tagged with 'Universal' class value '2', but it should have been 'Universal' class value '16'.”
.NET System.Security.Cryptography — ImportSubjectPublicKeyInfo / ImportPkcs8PrivateKey / ImportRSAPrivateKey / ImportECPrivateKey
含义
传给某个 `Import…` 方法的字节,并不是该方法所解码的 ASN.1 结构。每个方法只读取一种结构——PKCS#8、PKCS#1、SEC 1 或 SubjectPublicKeyInfo——而外层 DER 不匹配,因此 .NET 报告数据已损坏,尽管密钥本身可能完全没问题,只是采用了另一种格式。内部的 `AsnContentException` 会指出标签不匹配。
原因
PKCS#1 与 PKCS#8(或 SEC 1)混淆
常见把 `RSA PRIVATE KEY` 的字节传给了 `ImportPkcs8PrivateKey`,或者把 `PRIVATE KEY` 的字节传给了 `ImportRSAPrivateKey`。这两种结构的第一个元素不同(INTEGER 与 SEQUENCE)。
把 PEM 文本或 base64 当作 DER 传入
常见对包括首尾封装行在内的整个文件调用 `Encoding.ASCII.GetBytes(pem)` 或 `Convert.FromBase64String`,得到的都不是 DER。
公钥方法与私钥方法用反了
偶见把私钥传给了 `ImportSubjectPublicKeyInfo`,或者把证书(而不是密钥)传给了任何一个密钥导入方法。
修复方法
- 1.
对 PEM 文件使用 ImportFromPem
它根据 PEM 标签分派到对应的解码器,避免手动选错 DER 解码器。证书则改用 `X509Certificate2` 处理。
csharp // .NET 5+: ImportFromPem reads the label and picks the right decoder // (PRIVATE KEY, RSA PRIVATE KEY, EC PRIVATE KEY, PUBLIC KEY, RSA PUBLIC KEY). using var key = ECDsa.Create(); key.ImportFromPem(File.ReadAllText("key.pem")); - 2.
让方法与 DER 结构相匹配
如果必须处理原始 DER,就根据数据的实际类型选择导入方法;ASN.1 查看器可以告诉你手上是哪种结构。
csharp // DER input: choose the method by structure rsa.ImportPkcs8PrivateKey(der, out _); // "PRIVATE KEY" rsa.ImportRSAPrivateKey(der, out _); // "RSA PRIVATE KEY" rsa.ImportSubjectPublicKeyInfo(der, out _); // "PUBLIC KEY" rsa.ImportRSAPublicKey(der, out _); // "RSA PUBLIC KEY" ecdsa.ImportECPrivateKey(der, out _); // "EC PRIVATE KEY"