繁体   English   中英

RSA 公钥未导入 C# - ASN1 数据损坏异常

[英]RSA Public key not importing into C# - ASN1 corrupted data exception

我正在使用 Crypto library在 Python 中创建一组 RSA 密钥,然后导出公钥,并将其发送到 .NET Core 6 应用程序。 但是 .NET 无法读取公钥。

Python 加密库代码 - 此代码在 Ubuntu Linux 开发 PC 上运行:

key = RSA.generate(2048)
public_key = base64.b64encode(key.publickey().exportKey()).decode('utf8')

C# 代码 - 这是在 Windows 10 开发 PC 上运行的:

byte[] publicKeyBytes = Convert.FromBase64String(base64PublicKey);
RSA rsa = RSA.Create();
rsa.ImportRSAPublicKey(publicKeyBytes, out int bytesRead);

我收到的错误是:

AsnContentException:提供的数据标记为“通用”class 值“13”,但它应该是“通用”class 值“16”。

看看这篇 SO 文章这个 GitHub 问题,看起来我需要不同的导入方法。 所以我也尝试将最后一行更改为:

rsa.ImportSubjectPublicKeyInfo(publicKeyBytes, out int bytesRead);

但我得到了完全相同的错误。 只有堆栈跟踪有点不同,因为它使用了不同的提供程序。

如果有帮助,下面是 Crypto 库的export_key()方法的完整帮助文本的链接。 但这是我认为最相关的部分,是什么让我认为ImportSubjectPublicKeyInfo()会起作用:

对于公钥,此(pkcs)参数将被忽略。 对于 DER 和 PEM,始终使用 ASN.1 DER SubjectPublicKeyInfo 结构。

编辑:这可能与编码有关,或者可能与库之间的小端与大端问题有关......

这是 exportKey() function 的完整描述的链接。

编辑:重要的部分原来是format参数默认为 PEM 格式。

在 Python 端, key.publickey().exportKey()返回 X.509/SPKI 格式的 PEM 编码密钥。 不需要额外的 Base64 编码:

from Crypto.PublicKey import RSA

key = RSA.generate(2048)
public_key = key.publickey().exportKey().decode('utf8')
print(public_key)

给出例如:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5mPsHC34l7uz/Qlxma0s
fibiql2hcqbNVG/jyW6qAD9w+L9/ZBmaSo+wLMKI+xXVp5aHqDlgS07PxcWWLXFf
FLwdIk12rEXisbEPIj+3O+Fayqvk9NuUh9sDiVGOX7pMlnICFc+CdB3mK0sFRGkK
zOq3FJO19VxhzAI0dPQ6HDD4SLz/onuOoYMpcVfPa6bWDEe9MBCc1U+ypn9JNaq+
WrUjEw5RJbYCz451WPLa6wMKyIwA0EPck+h1yQc9+VCXwoK97awKE7wEPBwEG9HV
7UYMLJiVGvPkJypR+9+h/3M7CGVruhQwZG9Cz7QEqNm7oBQuyki5jyFAQueq8nKd
kwIDAQAB
-----END PUBLIC KEY-----

在 C# 端,可以使用RSA.ImportFromPem()直接导入 PEM 编码的密钥,自 .NET 5 起可用。
或者RSA.ImportSubjectPublicKeyInfo()可用于导入 X.509/SPKI 格式的公钥,该格式自 .NET Core 3.0 起可用。 但是,这只能导入 DER 编码的密钥。 从 PEM 编码的密钥中,可以通过删除 header、页脚和换行符以及 Base64 解码 rest 轻松导出 DER 编码密钥。
由于您正在使用 .NET 6 并且两种实现都可用, RSA.ImportFromPem()是最方便的:

using System.Security.Cryptography;
...
string pemX509 = @"-----BEGIN PUBLIC KEY-----
                MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5mPsHC34l7uz/Qlxma0s
                fibiql2hcqbNVG/jyW6qAD9w+L9/ZBmaSo+wLMKI+xXVp5aHqDlgS07PxcWWLXFf
                FLwdIk12rEXisbEPIj+3O+Fayqvk9NuUh9sDiVGOX7pMlnICFc+CdB3mK0sFRGkK
                zOq3FJO19VxhzAI0dPQ6HDD4SLz/onuOoYMpcVfPa6bWDEe9MBCc1U+ypn9JNaq+
                WrUjEw5RJbYCz451WPLa6wMKyIwA0EPck+h1yQc9+VCXwoK97awKE7wEPBwEG9HV
                7UYMLJiVGvPkJypR+9+h/3M7CGVruhQwZG9Cz7QEqNm7oBQuyki5jyFAQueq8nKd
                kwIDAQAB
                -----END PUBLIC KEY-----";
RSA rsa = RSA.Create();
rsa.ImportFromPem(pemX509);

为了完整起见: RSA.ImportRSAPublicKey()从 .NET Core 3.0 开始可用,用于导入 PKCS#1 格式的 DER 编码公钥,这不适用于导出的密钥。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM