RSA,JAVA私钥加密,C#公钥解密
2017-05-02 22:12
711 查看
做这个东西在坑里爬了3天才爬出来,记录下供园友参考。C#程序员一枚,项目需要和Java做数据交互,对方甩了段密文和一个CER证书给我,然后我要对其密文进行解密。 RSA 非对称加密,对方用私钥加密,我用公钥解密。关于证书的一点说明:证书类型有两种 .pfx 和 .cer ,其中 .pfx 证书既包含公钥也包含私钥, 而 .cer 证书只包含公钥。
C#默认RSA只支持公钥加密,私钥解密。而现在的需求正好相反,因此想要直接用C#内置加密类肯定是行不通的。而且C#和Java的RSA加密并不互通。经过多方资料查找,采用第三方类库 BouncyCastle 实现了当前需求。具体来看代码,这里贴出主要代码段:
1. 从cer证书中读取公钥。C#中的公钥格式是xml格式的字符串,与java中的公钥格式是不一样的。
2. 将C#格式公钥转换成Java格式公钥
3. 公钥解密。因为对方给的密文是经过base64编码的,所以要先解码。而且加密填充模式要设置成和java那边的一致,我这里设置的是 "RSA/ECB/PKCS1Padding"。
以上代码都依赖于 BouncyCastle 使用前记得先添加引用。为什么这样一个问题在坑里呆了3天呢?原因是Java那边返给我的密文格式是错误的,导致我怎么也解不出来。当时那个急的,还以为Java和C#实现不了互通加解密呢!最后这个问题还是我自己找出来的,丢了张截图给他们
就是这个原因,导致我加了两天班.... 当你解密时遇到 Unknown block type 错误时,很大可能性就是编码的问题,即密文的格式不正确。
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 错误时,很大可能性就是编码的问题,即密文的格式不正确。
相关文章推荐
- c# RSA 加密解密 java.net公钥私钥转换 要解密的模块大于128字节
- C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法
- C# RSA加密、解密、加签、验签、支持JAVA格式公钥私钥、PEM格式公钥私钥、.NET格式公钥私钥、一般模式【支持公钥加密,私钥解密】(一)
- RSA,JAVA私钥加密,C#公钥解密
- 整合一个基于c#的RSA私钥加密公钥解密的Helper类,含源码
- 关于JAVA中RSA加签解签,私钥加密公钥解密和公钥加密私钥解密代码步骤
- 整合一个基于c#的RSA私钥加密公钥解密的Helper类,含源码
- C#使用RSA进行私钥加密公钥解密
- RSA加密:Windows Phone 公钥加密,Java私钥解密
- JAVA 获取RSA非对称加密,私钥加密、公钥解密
- 整合一个基于C#的RSA私钥加密公钥解密的Helper类,含源码
- RSA公钥加密私钥解密--jsp加密,java解密
- C#使用RSA私钥加密公钥解密的改进,解决特定情况下解密后出现乱码的问题
- C#使用RSA进行私钥加密公钥解密
- 关于JAVA中RSA加签解签,私钥加密公钥解密和公钥加密私钥解密代码详解
- 整合一个基于c#的RSA私钥加密公钥解密的Helper类,含源码
- java 实现RSA实现数据的私钥加密以及公钥解密
- 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#
- 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#
- openssl rsa 私钥加密,公钥解密测试