C# RSA加密解密方法 C#如何使用RSA进行非对称加密

发布时间 - 2026-01-31 00:00:00    点击率:
RSA密钥跨平台解密失败主因是格式不兼容:.NET默认导出PKCS#8私钥和SubjectPublicKeyInfo公钥,而Python/Node.js等常需PKCS#1格式(-----BEGIN RSA PUBLIC KEY-----);应导出时选ExportSubjectPublicKeyInfo()和ExportRSAPrivateKey()以提升兼容性。

为什么直接用 RSA.Create() 生成的密钥不能跨平台解密

因为 .NET 默认使用的是 Windows CNG(Cryptography Next Generation)实现,生成的密钥默认是 RSACng 类型,私钥导出格式为 PKCS#8(带密码保护时可能加密),而公钥是 SubjectPublicKeyInfo 格式。但很多其他语言(如 Python 的 cryptography、Node.js 的

crypto)默认期望 PEM 封装的 PKCS#1 格式公钥/私钥(即以 -----BEGIN RSA PUBLIC KEY----- 开头)。不转换格式就传给对方,必然解密失败。

实操建议:

  • 导出公钥时,优先用 ExportSubjectPublicKeyInfo()(对应 PEM 中 -----BEGIN PUBLIC KEY-----),这是跨语言兼容性最好的选择;
  • 导出私钥时,若需给其他语言用,避免用 ExportPkcs8PrivateKey()(.NET 6+ 默认),改用 ExportRSAPrivateKey() 得到 PKCS#1 格式(-----BEGIN RSA PRIVATE KEY-----),但注意:该方法导出的是未加密私钥,务必确保传输和存储安全;
  • 如果对方坚持要 PKCS#8 无密码私钥(比如 Java 的 PKCS8EncodedKeySpec),可用 ExportPkcs8PrivateKey(),再用 OpenSSL 转换:openssl pkcs8 -topk8 -nocrypt -in key.pk8 -out key.pem

RSA.Encrypt() 报错“Data too large for key size”怎么处理

RSA 本身不能直接加密长数据,它有严格的明文长度限制:对 2048 位密钥,PKCS#1 v1.5 填充下最多加密 245 字节;OAEP 填充下约 190 字节。超过就会抛出 CryptographicException: Data too large for key size

这不是 bug,是 RSA 的数学约束。真实场景中必须分层处理:

  • 用 RSA 加密一个随机生成的 256 位 AES 密钥(即“信封加密”);
  • 用这个 AES 密钥 + AesGcmAesCbc 加密实际数据;
  • 把加密后的 AES 密钥和 AES 密文一起发送;
  • 接收方先用 RSA 解密出 AES 密钥,再用它解密数据。

别试图手动分块加密——RSA 分块不仅低效,还破坏语义安全性,且不同填充方式无法简单拼接。

如何安全地序列化和反序列化 RSA 密钥(尤其在 ASP.NET Core 配置中)

密钥不能硬编码,也不该以明文形式存进 appsettings.json。推荐做法是分离存储:

  • 私钥走操作系统级保护:Windows 用 CngKey.Import() + DPAPI,Linux/macOS 用 System.Security.Cryptography.X509Certificates 加载 PFX 并设 X509KeyStorageFlags.EphemeralKeySet
  • 公钥可安全暴露:用 ExportSubjectPublicKeyInfo() 得到字节数组,再转 Base64 存配置,加载时用 ImportSubjectPublicKeyInfo() 还原;
  • 如果必须存私钥字符串(如容器环境),至少用环境变量 + AES-GCM 加密后再存,启动时用 KMS(如 Azure Key Vault、AWS KMS)解密密钥本身;
  • 绝对不要用 ExportParameters(true) 输出 RSAPrivateCrtKey 结构体——它包含所有素数分量,一旦泄露等于私钥彻底暴露。

为什么用 RSASignaturePadding.Pkcs1 签名后,OpenSSL 验证失败

签名算法 ≠ 哈希算法。.NET 的 SignData() 默认只做签名运算,不自动哈希;而 OpenSSL 的 openssl dgst -sha256 -sign 是先哈希再签名。两者行为不一致就会验签失败。

正确对齐方式:

  • 如果对方用 openssl dgst -sha256 -sign key.pem,你必须在 C# 中先算 SHA256 哈希,再调用 SignHash(),并指定 RSASignaturePadding.Pkcs1
  • 更推荐统一用 SignData() + RSASignaturePadding.Pss(带盐值),它内部自动哈希(默认 SHA256),且 PSS 是现代标准,OpenSSL 也支持(openssl pkeyutl -sign -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss);
  • 验证时务必用匹配的填充和哈希:PSS 签名必须用 VerifyData() + RSASignaturePadding.Pss,不能混用 Pkcs1。

密钥长度、填充方式、哈希算法这三项必须全部对齐,少一个都会验证失败——而且错误信息往往只报“验证失败”,不会告诉你哪一项不匹配。


# linux  # python  # java  # js  # node.js  # json  # node  # windows  # 操作系统  # 编码  # app  # for  # 封装  # 字符串  # 结构体  # public  # private 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  北京专业网站制作设计师招聘,北京白云观官方网站?  UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】  Laravel如何实现邮件验证激活账户_Laravel内置MustVerifyEmail接口配置【步骤】  如何在IIS管理器中快速创建并配置网站?  三星网站视频制作教程下载,三星w23网页如何全屏?  如何快速启动建站代理加盟业务?  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】  使用豆包 AI 辅助进行简单网页 HTML 结构设计  Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  音响网站制作视频教程,隆霸音响官方网站?  HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】  如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  实例解析angularjs的filter过滤器  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  怎么用AI帮你为初创公司进行市场定位分析?  网站制作软件免费下载安装,有哪些免费下载的软件网站?  如何用PHP工具快速搭建高效网站?  HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】  太平洋网站制作公司,网络用语太平洋是什么意思?  Laravel如何创建自定义中间件?(Middleware代码示例)  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】  Swift开发中switch语句值绑定模式  Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID  Laravel如何实现文件上传和存储?(本地与S3配置)  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  使用Dockerfile构建java web环境  Laravel用户密码怎么加密_Laravel Hash门面使用教程  Android实现代码画虚线边框背景效果  canvas 画布在主流浏览器中的尺寸限制详细介绍  *服务器网站为何频现安全漏洞?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  智能起名网站制作软件有哪些,制作logo的软件?  Win11怎么设置默认图片查看器_Windows11照片应用关联设置  PHP 500报错的快速解决方法  Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  Laravel storage目录权限问题_Laravel文件写入权限设置  laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法  php做exe能调用系统命令吗_执行cmd指令实现方式【详解】  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  在centOS 7安装mysql 5.7的详细教程  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  Laravel如何实现本地化和多语言支持?(i18n教程)  Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】  🚀拖拽式CMS建站能否实现高效与个性化并存?