一般对接第三方的接口时,接口提供方如果要求以RSA方式进行加密传输,并且给了你一串字符串说是RSA加密公钥,那么该公钥一般是PEM格式文件的base64字符串表现形式。

完整PEM格式示例:

1:示例证书:

-----BEGIN RSA PRIVATE KEY-----

base64字符串

-----END RSA PRIVATE KEY-----

注意其格式,接口提供方有可能只给你中间的base64字符串,也有可能将完整的格式内容都给你,那么你要留意去除除了base64字符串内容之外的头尾以及空行。

那么问题来了,在C#的RSA加密工具类RSACryptoServiceProvider中,并没有支持PEM格式公钥为基准的加密方法,只能用一种.net平台认可的xml字符串的公钥才能够进行加密。

RSACryptoServiceProvider _rsa = new RSACryptoServiceProvider();
_rsa.FromXmlString(publickey);//这里的公钥指定只能是平台认可的xml字符串格式,直接传入pem的base64是不行的
byte[] cipherbytes = _rsa.Encrypt(_b, false);//进行加密

想要从pem公钥转为xml公钥,只能依赖于一个第三方库,叫做BouncyCastle

然后用以下方法进行转换:

/// <summary>
/// RSA公钥pem的base64字符串-->XML格式字符串转换,
/// </summary>
/// <param name="publicKey">pem公钥base64字符串</param>
/// <returns></returns>
public static string RSAPublicKey(string publicKey)
{RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));string XML = string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));return XML;
}

另外如果在之后加密时报长度超长之类的错误,说明需要分段加密,因为RSA的加密机制要求:待加密的字节数不能超过密钥的长度值除以 8 再减去 11。

可以用如下方法进行分段加密:

/// <summary>
/// RSA加密并且返回加密后内容的base64字符串
/// </summary>
/// <param name="publickey">公钥xml格式字符串</param>
/// <param name="content">加密内容</param>
/// <returns></returns>
public static string RSAEncrypt(string publickey, string content)
{RSACryptoServiceProvider _rsa = new RSACryptoServiceProvider();_rsa.FromXmlString(publickey);var _b = Encoding.Default.GetBytes(content);//将字符编码转为utf8_b = Encoding.Convert(Encoding.Default, new UTF8Encoding(), _b);int _maxSize = _rsa.KeySize/8-11;if (_b.Length <= _maxSize){byte[] cipherbytes = _rsa.Encrypt(_b, false);return Convert.ToBase64String(cipherbytes);}else//分块加密{using (MemoryStream PlaiStream = new MemoryStream(_b))using (MemoryStream CrypStream = new MemoryStream()){Byte[] Buffer = new Byte[_maxSize];int BlockSize = PlaiStream.Read(Buffer, 0, _maxSize);while (BlockSize > 0){Byte[] ToEncrypt = new Byte[BlockSize];Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);Byte[] Cryptograph = _rsa.Encrypt(ToEncrypt, false);CrypStream.Write(Cryptograph, 0, Cryptograph.Length);BlockSize = PlaiStream.Read(Buffer, 0, _maxSize);}return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);}}
}

但是上面的加密方式有一个问题,就是同样的待加密内容和公钥,每次加密之后的结果都不相同,虽然都能用私钥进行解密。如果是那种涉及到MD5验证之类的摘要算法进行验证,那么这种“加密结果不固定”的加密方式就不可取了。

之所以出现这种问题是与RSA加密算法的“填充(Padding)”有关,这里的东西我也不懂,所以略过,有兴趣的同学可以深入研究一下。

所以基于这种情况,下面的方法就是一种无填充的公钥加密方式,可以让每一次的加密结果都一致:

/// <summary>/// RSA公钥加密(无填充,结果不变)/// </summary>/// <param name="clearText">待加密内容的字节数组</param>/// <param name="publicKey">公钥(无pem格式头尾,仅base64部分)</param>/// <returns>加密结果的字节数组</returns>public byte[] RsaEncryptWithPublic(byte[] srcData, string publicKey){var encryptEngine = new RsaEngine(); // new Pkcs1Encoding (new RsaEngine());using (var txtreader = new StringReader("-----BEGIN PUBLIC KEY-----\n" + publicKey + "\n-----END PUBLIC KEY-----")){var keyParameter = (AsymmetricKeyParameter)new Org.BouncyCastle.OpenSsl.PemReader(txtreader).ReadObject();encryptEngine.Init(true, keyParameter);}byte[] _resultBytes;var _maxSize = encryptEngine.GetInputBlockSize();if (srcData.Length <= _maxSize){_resultBytes = encryptEngine.ProcessBlock(srcData, 0, srcData.Length);}else//分块加密{using (MemoryStream PlaiStream = new MemoryStream(srcData))using (MemoryStream CrypStream = new MemoryStream()){Byte[] Buffer = new Byte[_maxSize];int BlockSize = PlaiStream.Read(Buffer, 0, _maxSize);while (BlockSize > 0){Byte[] ToEncrypt = new Byte[BlockSize];Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);Byte[] Cryptograph = encryptEngine.ProcessBlock(ToEncrypt, 0, ToEncrypt.Length);CrypStream.Write(Cryptograph, 0, Cryptograph.Length);BlockSize = PlaiStream.Read(Buffer, 0, _maxSize);}_resultBytes = CrypStream.ToArray();}}return _resultBytes;}

关于C#的RSA加密相关推荐

  1. Python加密—RSA加密

    为什么80%的码农都做不了架构师?>>> 公钥加密,私钥解密. import rsa import base64 from Crypto.PublicKey import RSA # ...

  2. iOS使用Security.framework进行RSA 加密解密签名和验证签名

    iOS 上 Security.framework为我们提供了安全方面相关的api: Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,10 ...

  3. RSA加密传输代码示例

    RSA加密传输代码示例 涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了. 服务端可以保留自己的私钥,发给客户端对应的公钥.这样就可以互相加解密了.php中rsa加解密实现 ...

  4. ios android rsa加密解密,IOS RSA加密解密

    最近项目中对接口进行了rsa 加密. 写下过程以便复习 公钥私钥一般是有后台给的,这里为了方便 自己生成一对秘钥 生成公钥 私钥. 终端中: 生成原始 RSA私钥文件 private_key.pem ...

  5. python后端开发框架加密_Flask框架实现的前端RSA加密与后端Python解密功能详解

    本文实例讲述了Flask框架实现的前端RSA加密与后端Python解密功能.分享给大家供大家参考,具体如下: 前言 在使用 Flask 开发用户登录API的时候,我之前都是明文传输 username ...

  6. 一篇搞定RSA加密与SHA签名|与Java完全同步

    看到这篇文章的同学可幸福了,当时在做RSA加密与签名的时候网上的资料简直不要太老,做完后实在是忍受不下去了,这篇文章我会详细讲解iOS如何实现RSA加密与签名,并且与Java完全同步,这是我的第二篇博 ...

  7. linux 加密可逆,RSA加密是可逆的吗

    java rsa加密可逆吗可逆.有秘钥就成. linux上RSA加密每次都变化吗 加密解密的技术: 对称加密 加密方和解密方使用是同一个密钥,加密解密的速度都很快,先将数据明文 分成数据块儿,一般来讲 ...

  8. python3 rsa加密_【Python】Python3 实现 JS 中 RSA 加密的 NoPadding 模式

    前因后果之哗啦啦废话连篇: 这几天本人在 Python 做某网站登陆的时候,发现其登陆时用户名和密码被加密了 F12 仔细看了一下,发现是调用了一个 js 的 rsa 加密库,页面 dom 中有 rs ...

  9. obj c和java_PKCS1-padding / RSA加密ios objc和java之间的区别

    我正在为ios和Android开发应用程序.我对加密任务相对来说比较陌生,在过去的3天里,由于无法运行RSA加密,所以我一直在抨击我的头部. 两个客户端都从java服务器接收公钥.在Android中我 ...

  10. iOS安全之RSA加密/生成公钥、秘钥 pem文件

    在iOS中使用RSA加密解密,需要用到.der和.p12后缀格式的文件,其中.der格式的文件存放的是公钥(Public key)用于加密,.p12格式的文件存放的是私钥(Private key)用于 ...

最新文章

  1. Ubuntu 14.04上安装pip3/numpy/matplotlib/scipy操作步骤
  2. 【百度地图API】如何制作班级地理通讯录?LBS通讯录
  3. 三代测序之全长转录本
  4. Managed Extensibility Framework (MEF)
  5. spintboot学习笔记
  6. BS-XX-026 基于SpringBoot 实现个人理财系统
  7. 将程序添加到自动启动
  8. Jmeter之ForEach控制器(配合正则表达式使用)
  9. Spring MVC之表单标签
  10. js java 反射机制_java 类加载机制和反射机制
  11. android添加删除项目,编写android计算器添加删除按钮,出现很抱歉,XX项目已停止运行。...
  12. Description Resource Path Location Type Project configuration is not up-to-date with pom.xml. Select
  13. Oracle 11g 数据恢复 数据误删除后的恢复 0、执行 select log_mode from v$database;查看是否为归档模式 1、确定删除时间和被删除的表 04-23,GR
  14. python 金融可视化_Python数据分析:金融数据可视化
  15. 向Windows 日志管理器写入系统程序日志信息
  16. 从阿尔法狗元(AlphaGo Zero)的诞生看终极算法的可能性
  17. 基于华为云IoT设计的智能门锁
  18. 关于win10声卡驱动正常 插入耳机小喇叭显示红叉号 且检测提示未插入耳机的问题
  19. 抖音python广告用的什么音乐_被抖音捧火的几首纯音乐,都是你们要的原版,太震撼人心!...
  20. 2020年复旦大学计算机学院夏令营经历

热门文章

  1. 美图祛斑算法实战——雀斑消除
  2. 截至18日下午两点京东618下单金额破2392亿!主场地位不可动摇
  3. JS定时器,距离XX天还有XX的倒计时
  4. 画正方形代码(c++)
  5. HFSS学习笔记 2 建模过程和长方体建模步骤
  6. Win10系统通信端口初始化失败
  7. js正则校验日期格式和时间格式是否正确
  8. MATLAB提取感兴趣ROI
  9. 计算机硬盘是什么形状,四种最常见的SSD硬盘的外形、应用及未来市场发展
  10. 2021-12-16 《聪明的投资者》学习笔记-13.对四家上市公司的比较--普通了解,不必强求