.NET 6+ 推荐用 RSA.Create() 生成密钥对,导出私钥用 ExportRSAPrivateKey()、公钥用 ExportRSAPublicKey(),确保使用 OAEP 或 PKCS1 填充,加密用公钥、解密用私钥,密钥需转 PEM 格式(加头尾标记)以跨平台兼容。

怎么用 RSA 类生成密钥对(.NET 6+ 推荐方式)
直接用 RSA.Create(),别碰过时的 RSACryptoServiceProvider —— 它在 .NET Core / .NET 5+ 已标记为过时,且不支持跨平台密钥导出。
生成密钥对后,必须明确区分「私钥」和「公钥」用途:私钥只能自己保存,公钥可分发;导出时也得选对方法,否则解密会失败。
-
RSA.ExportParameters(includePrivateParameters: true)才能拿到私钥数据,false只导出公钥部分 - 导出的
RSAParameters不是字符串,要转成 PEM 或 XML 才能存文件或传网络 - .NET 6+ 建议用
RSA.ExportRSAPrivateKey()和RSA.ExportRSAPublicKey()直接得字节数组,兼容 OpenSSL 格式
公钥加密、私钥解密的实际写法(别反了)
常见错误是把加密逻辑写反:用私钥加密、公钥解密——这不是 RSA 的常规用法,而是签名场景。加解密流程必须是:公钥加密 → 私钥解密。
注意 RSA.Encrypt() 默认使用 OAEP 填充(推荐),但老系统可能只认 PKCS1,得显式指定 RSASignaturePadding.Pkcs1 或 RSASignaturePadding.OaepSHA256。
- 加密前检查明文长度:OAEP 模式下,最大明文长度 ≈ 密钥长度(bit)/ 8 − 66,2048 位密钥最多加密约 190 字节
- 解密失败报
CryptographicException: The parameter is incorrect,大概率是用了错的 padding 或密钥类型不匹配 - 别把
Encrypt()和SignData()混用,函数名看着像,语义完全不同
怎么安全保存和加载密钥(尤其跨环境)
开发机上生成的密钥,放到 Linux 服务器跑不起来?多半是导出格式或编码问题。.NET 默认导出的是二进制 PKCS#8(私钥)和 X.509(公钥),不是 OpenSSL 常见的 PEM 文本。
想让密钥被其他语言(如 Python、Node.js)读取,必须转成 PEM 并手动加头尾标记。别依赖自动识别——没有标准头,OpenSSL 就当它是垃圾。
- 用
Convert.ToBase64String(rsa.ExportRSAPrivateKey())后,手动拼接"-----BEGIN PRIVATE KEY-----"和"-----END PRIVATE KEY-----" - 公钥同理,用
ExportRSAPublicKey()+-----BEGIN PUBLIC KEY----- - Windows 上用
ExportCspBlob()导出的密钥,Linux 下完全无法加载,彻底弃用
为什么 RSA.Create(2048) 生成的密钥,Java 解不出来
根本原因不是位数不对,而是密钥结构差异:.NET 默认导出的是 PKCS#8 私钥(含算法标识),而很多 Java 库(比如 Bouncy Castle 旧版)默认只认传统的 PKCS#1 格式(RSAPrivateKey ASN.1 结构)。
还有个隐蔽坑:.NET 的 ExportRSAPrivateKey() 输出的是未加密的 PKCS#8,但某些 Java 工具要求带密码保护的 PKCS#8(即 EncryptedPrivateKeyInfo),不匹配就直接抛异常。
- 用 OpenSSL 转换格式:
openssl pkcs8 -topk8 -inform DER -outform PEM -in private.der -nocrypt - Java 端确认是否调用了
PKCS8EncodedKeySpec(对应 PKCS#8)还是RSAPrivateKeySpec(对应 PKCS#1) - 密钥导出前务必验证:用
openssl rsa -in key.pem -check看是否合法
密钥格式和填充方式这两个点,比算法本身更容易卡住人。没报错但结果不对,先查这两块。










