RSA,JAVA私钥加密,C#公钥解密

做这个东西在坑里爬了3天才爬出来,记录下供园友参考。C#程序员一枚,项目需要和Java做数据交互,对方甩了段密文和一个CER证书给我,然后我要对其密文进行解密。 RSA 非对称加密,对方用私钥加密,我用公钥解密。关于证书的一点说明:证书类型有两种 .pfx 和 .cer ,其中 .pfx 证书既包含公钥也包含私钥, 而 .cer 证书只包含公钥。

C#默认RSA只支持公钥加密,私钥解密。而现在的需求正好相反,因此想要直接用C#内置加密类肯定是行不通的。而且C#和Java的RSA加密并不互通。经过多方资料查找,采用第三方类库 BouncyCastle 实现了当前需求。具体来看代码,这里贴出主要代码段:

1. 从cer证书中读取公钥。C#中的公钥格式是xml格式的字符串,与java中的公钥格式是不一样的。

/// <summary>
/// 从证书中获取公钥
/// </summary>
/// <param name="cerPath"></param>
/// <returns></returns>
private string GetPublicKeyFromCer(string cerPath)
{
     X509Certificate2 pubcrt = new X509Certificate2(cerPath);
     RSACryptoServiceProvider pubkey = (RSACryptoServiceProvider)pubcrt.PublicKey.Key;

     return pubkey.ToXmlString(false);
}

2. 将C#格式公钥转换成Java格式公钥

/// <summary>
/// 将C#格式公钥转成Java格式公钥
/// </summary>
/// <param name="publicKey"></param>
/// <returns></returns>
public static RsaKeyParameters RSAPublicKeyDotNet2Java(string publicKey)
{
     XmlDocument doc = new XmlDocument();
     doc.LoadXml(publicKey);
     BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
     BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
     RsaKeyParameters pub = new RsaKeyParameters(false, m, p);

     return pub;
}

3. 公钥解密。因为对方给的密文是经过base64编码的,所以要先解码。而且加密填充模式要设置成和java那边的一致,我这里设置的是 "RSA/ECB/PKCS1Padding"。

/// <summary>
/// 公钥解密
/// </summary>
/// <param name="xmlPublicKey">C#格式公钥</param>
/// <param name="strEncryptString">密文</param>
/// <returns></returns>
public static string RSADecryptByPublicKey(string xmlPublicKey, string strEncryptString)
{
      //得到公钥
      RsaKeyParameters keyParams = RSAPublicKeyDotNet2Java(xmlPublicKey);

      //参数与Java中加密解密的参数一致
      IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");  

      //第一个参数 true-加密,false-解密;第二个参数表示密钥
      c.Init(false, keyParams);

      //对密文进行base64解码
      byte[] dataFromEncrypt = Convert.FromBase64String(strEncryptString);

      //解密
      byte[] outBytes = c.DoFinal(dataFromEncrypt);

      //明文
      string clearText = Encoding.Default.GetString(outBytes);

      return clearText;
}

以上代码都依赖于 BouncyCastle 使用前记得先添加引用。为什么这样一个问题在坑里呆了3天呢?原因是Java那边返给我的密文格式是错误的,导致我怎么也解不出来。当时那个急的,还以为Java和C#实现不了互通加解密呢!最后这个问题还是我自己找出来的,丢了张截图给他们

就是这个原因,导致我加了两天班.... 当你解密时遇到 Unknown block type 错误时,很大可能性就是编码的问题,即密文的格式不正确。

时间: 2024-10-13 16:12:42

RSA,JAVA私钥加密,C#公钥解密的相关文章

C# RSA加密、解密、加签、验签、支持JAVA格式公钥私钥、PEM格式公钥私钥、.NET格式公钥私钥 -变态模式【支持私钥加密,公钥解密】(二)

RSA变态模式:[私钥加密,公钥解密] 一般这种写法都是JAVA弄的..NET原生不支持.为啥,我也不清楚,大概是因为安全性问题吧,毕竟公钥是人人都可是持有的.私钥只有自己拥有. 对接注意事项:https://www.cnblogs.com/kevin860/p/9557845.html 一般方法请看:https://www.cnblogs.com/kevin860/p/9557845.html 签名一直都是[私钥加签.公钥验签]只为证明该消息是你发出来的. 这里使用了BouncyCastle1

C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法

因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger开源类来实现,不过那个是有一个文章,不过他加密出来的是16进制结果的.根本不能和JAVA互通.连加密出来的都不和C#原生的加密出来的结果格式一样.所以还是没有好的解决方法. 接下来还是不断的找资料,找方法.找朋友找同事.个个都找.问题是有的,方法也是有的,所以总结各路大神之后写了这个类.实现了私钥加

Delphi RSA加解密【 (RSA公钥加密,私钥解密)、(RSA私钥加密,公钥解密)、MD5加密、SHA加密】

作者QQ:(648437169) delphi RSA加解密 [Delphi RSA加解密]支持 (RSA公钥加密,私钥解密).(RSA私钥加密,公钥解密).MD5加密.SHA1加密.SHA224加密.SHA256加密.SHA384加密.SHA512加密 原文地址:https://www.cnblogs.com/zhimamaigua/p/11003504.html

Java中使用OpenSSL生成的RSA公私钥进行数据加解密

RSA是什么:RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的.RSA取名来自开发他们三者的名字.RSA是目前最有影响力的公钥加密算法,它能够 抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准.目前该加密方式广泛用于网上银行.数字签名等场合.RSA算法基于一个十分简单的 数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥. OpenSSL是什

RSA不对称加密和公钥 私钥

理论上只要有加密的规则 基本都是可以解密的 但是如果解密需要消耗的时间过长 比如1000年 解密过后已经没什么意义了 此时可认为这种算法不能被破解 也就是说此加密可信 MD5 是一种单向操作 加密后不能被还原 只能用于信息校验(相同的输入md5后的字符是相同的<_>) RSA 私钥 公钥 加密算法 是一种可以还原数据原型的算法  公钥加密的东西  只能用私钥解出来 即使公钥自身也解不出来  同理私钥加密的东西也只有公钥能解密出来  自身也解不出来 .所以二者是对等的 相互依赖的. 但是加入我们

JAVA生成RSA非对称型加密的公钥和私钥(利用JAVA API)

非对称型加密非常适合多个客户端和服务器之间的秘密通讯,客户端使用同一个公钥将明文加密,而这个公钥不能逆向的解密,密文发送到服务器后有服务器端用私钥解密,这样就做到了明文的加密传送. 非对称型加密也有它先天的缺点,加密.解密速度慢制约了它的发挥,如果你有大量的文字需要加密传送,建议你通过非对称型加密来把对称型‘密钥’分发到客户端,及时更新对称型‘密钥’. package com.paul.module.common.util; import sun.misc.BASE64Decoder; impo

RSA前台js加密,后台C#解密

一.需求: 为了安全,项目中前台登陆用的密码需要加密传到后台,后台c#解密登陆密码. 二.解决方案 采用非对称加密算法RSA来达到目的,前台登陆页面一加载便发送一次ajax请求获取后台产生的公钥,用于前台加密,用户点击登陆时出发加密过程并提交加密的数据到后台,后台C#语言采用已封装好的RSA算法工具进行密码解密. 以下为c#RSA算法加密代码: private static RSAParameters rsap = new RSAParameters() { Modulus = Convert.

rsa公私钥加密原理

假设爱丽丝的公钥是(3233, 17):加入发送65,公钥加密后的结果是2790 私钥(3233, 2753) 收到公钥加密的数据2790后,进行2790^2753次方后,得出结果再mod 3233就会得到65,恢复出原来的数据据结果 公钥(n,e) 私钥(n,d) 总共有2个密钥的数据加密数据的过程,m的e次方,(m^e) mod 3233,那么结果就是2790,就是得出的结果

浅谈IM软件业务知识——非对称加密,RSA算法,数字签名,公钥,私钥

概述 首先了解一下相关概念:RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的.RSA就是取自他们三个人的名字. 算法基于一个数论:将两个大素数相乘很easy,但要对这个乘积的结果进行 因式分解却很困难,因此可以把乘积公开作为公钥.该算法可以抵抗眼下已知的全部password攻击. RSA算法是一种非对称算法,算法须要一对密钥.使用当中一个 加密.须要使用另外一个才干解密.我们在进行RSA加密通讯时.就把公钥放在client,私钥留在server.