.NET 6+ 必须用 RSA.Create(2048) 生成密钥对,导出私钥用 ExportRSAPrivateKey()(PKCS#8 格式),公钥用 ExportRSAPublicKey()(SubjectPublicKeyInfo 格式),原生不支持 PEM 封装需手动拼接头尾。
别用
,它在 .NET 6+ 已过时且跨平台直接报
;所有新代码必须从
开始,密钥导出、加密、签名三者参数必须严格匹配填充方式与哈希算法,否则解密或验签必然失败。
怎么生成和导出密钥对(.NET 6+ 正确路径)
密钥生成必须调用
(或更高位数),不能
。导出时注意格式语义:
→ 返回 PKCS#8 格式私钥字节数组(OpenSSL 兼容,推荐)
→ 返回 SubjectPublicKeyInfo 格式公钥字节数组(标准 PEM 公钥内容,对应
)
.NET 原生不支持 PEM 封装,需手动拼接头尾:
硬编码
是陷阱:返回的
是结构体,无法跨平台序列化,也不含完整 PKCS#8 语义
的真实原因
这个错误 90% 不是密钥坏了,而是填充或长度不匹配:
加密时没显式指定
,只写
会退化为 SHA1(已不安全)
明文超长:2048 位密钥 + OAEP-SHA256 下,
必须 ≤
(约 190 字节),不是字符数
加密用了私钥、解密用了公钥——这是签名逻辑,不是加解密流程;RSA 加解密必须是「公钥加密 → 私钥解密」
解密时没用同一私钥字节数组重新导入,
对象不是长期可复用的“句柄”,每次操作建议新建并
签名和验签必须用
/
,别和
混用
签名不是“用私钥加密原文”,而是对摘要做数学运算,接口完全独立:
C知道
CSDN推出的一款AI技术问答工具
下载
签名:私钥调
(OAEP 不适用于常规签名)
验签:公钥调
,参数顺序、哈希、填充必须完全一致
和
只用于机密性;
和
只用于完整性与身份认证
把
结果当成“加密”再用公钥
去“解密”,结果永远失败
为什么不能直接用 RSA 加密用户数据(比如 JSON 或文件)
RSA 本身不能加密任意长度原始数据,这是数学约束,不是实现缺陷:
2048 位密钥下,PKCS#1 最多加密 245 字节,OAEP-SHA256 最多约 190 字节;传入 300 字节 UTF8 字符串必抛
真实场景必须用混合加密:每次请求新生成 AES 密钥,用 AES 加密数据,再用 RSA 加密该 AES 密钥(即“信封加密”)
别自己
拼接字节数组;用
写入长度头,否则接收方无法拆分 AES 密文和 RSA 加密后的 key/iv
私钥严禁以明文字符串形式存配置文件或日志;导出后应走安全存储(如 Azure Key Vault、Windows DPAPI、Linux keyring)
最易被忽略的点:填充方式和哈希算法必须在加密/解密、签名/验签两端**字面级一致**,哪怕只是
和
的差别,也会导致静默失败;还有就是误把
得到的 SubjectPublicKeyInfo 当成 PKCS#1 公钥传给 Python/Node.js,结果解密失败——它们默认期望的是
,得换格式或换库。
RSACryptoServiceProviderPlatformNotSupportedExceptionRSA.Create()RSA.Create(2048)new RSACryptoServiceProvider(2048)ExportRSAPrivateKey()ExportRSAPublicKey()-----BEGIN PUBLIC KEY-----"-----BEGIN RSA PRIVATE KEY-----\n" + Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks) + "\n-----END RSA PRIVATE KEY-----"ExportParameters(true)RSAParametersCryptographicException: The parameter is incorrect.RSAEncryptionPadding.OaepSHA256RSAEncryptionPadding.OaepEncoding.UTF8.GetBytes(input).Lengthrsa.KeySize / 8 - 42RSAImportRSAPrivateKey()SignData()VerifyData()Encrypt()SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)Encrypt()Decrypt()SignData()VerifyData()SignData()Encrypt()CryptographicException: Data too large for key sizeArray.CopyBinaryWriterOaepOaepSHA256ExportRSAPublicKey()-----BEGIN RSA PUBLIC KEY-----