前言

我们产品是使用JAVA语言开发的,有个供第三方获取Token的接口,过程大概就是第三方先调一个注册接口,获取一个RSA公钥,然后用通过公钥加密后的一些认证信息调用获取Token的接口,如果信息无误,则发放Token。

前段时间就遇到了对方是使用.Net进行开发的系统,在第一步获取公钥时没用问题,加密后的信息传过来就怎么都解密不了的情况,后来了解到,C#的默认密钥格式上似乎是略有不同才导致的问题。

NET Framework中,的RSACryptoServiceProvider默认使用Microsoft的专有格式

Java 通常使用PKCS#8格式的私钥和X.509格式的公钥

解决方案

其实C#中转换一下就可以了

示例代码

RsaApi.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System.Xml;
using System.Text;
using System.Security.Cryptography; namespace RsaApi
{
public class RSAConvert
{
/// <summary>
/// RSA私钥格式转换,java->.net
/// </summary>
/// <param name="privateKey">java生成的RSA私钥</param>
/// <returns></returns>
public static string RSAPrivateKeyJava2DotNet(string privateKey)
{
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
} /// <summary>
/// RSA私钥格式转换,.net->java
/// </summary>
/// <param name="privateKey">.net生成的私钥</param>
/// <returns></returns>
public static string RSAPrivateKeyDotNet2Java(string privateKey)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(privateKey);
BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText)); RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv); PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
return Convert.ToBase64String(serializedPrivateBytes);
} /// <summary>
/// RSA公钥格式转换,java->.net
/// </summary>
/// <param name="publicKey">java生成的公钥</param>
/// <returns></returns>
public static string RSAPublicKeyJava2DotNet(string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
} /// <summary>
/// RSA公钥格式转换,.net->java
/// </summary>
/// <param name="publicKey">.net生成的公钥</param>
/// <returns></returns>
public static string 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); SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
return Convert.ToBase64String(serializedPublicBytes);
} /// <summary>
/// rsa加密
/// </summary>
/// <param name="xmlPublicKey"></param>
/// <param name="m_strEncryptString"></param>
/// <returns></returns>
public static string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
{
try
{
byte[] PlainTextBArray;
byte[] CypherTextBArray;
string Result;
System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(xmlPublicKey);
PlainTextBArray = (new UTF8Encoding()).GetBytes(m_strEncryptString);
CypherTextBArray = rsa.Encrypt(PlainTextBArray, false);
Result = Convert.ToBase64String(CypherTextBArray);
return Result;
}
catch (Exception ex)
{
throw ex;
}
} }
}

Program.cs

using System.Security.Cryptography.X509Certificates;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography; using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto.Encodings; namespace Program
{
public class Program
{
private static Encoding Encoding_UTF8 = Encoding.UTF8;
public struct RSAKEY
{
public string PublicKey
{
get;
set;
}
public string PrivateKey
{
get;
set;
}
} //// 测试主方法
static void Main(string[] args)
{
Program p =new Program();
RSAKEY rsa = p.GetKey(); string publickey = rsa.PublicKey;
string privateKey = rsa.PrivateKey;
string s = p.EncryptByPublicKey("2882e099-c705-43ed-93a3-02cb2cd67559","MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtGlTbBJzXF1fVv/+cB37QUwC5bmlm+p5KIuPIMuPX4PrhXl63R3e2bCfwhootzUdOcmmFAX6f9fWBj1Bc4lQem+FvFvE3Y53tNvGUdlNakysfXAVF8Q1PnPyGrVqiEsTHt3WMq/8vD29XJQMQ1FRvHZfY60ptypvNvvzES9JxC66RYskPHmTnerIRFzmXAJ0GUavpT3smg+K+vM5aSgfYbnuoANJTb4RMh358GTkTt4dAXRn0qpbhO+7+xbxmfOzHH9jlJ66JQr7q+W2PawNXnE4xsdwQ/1D0hT78zniTTaFyvfxBOQzx/6o1MNTZAWyhuSw7niJXUNGySJRS87OJQIDAQAB");
Console.WriteLine(s);
}
public RSAKEY GetKey()
{
//RSA密钥对的构造器
RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator(); //RSA密钥构造器的参数
RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
Org.BouncyCastle.Math.BigInteger.ValueOf(3),
new Org.BouncyCastle.Security.SecureRandom(),
1024, //密钥长度
25);
//用参数初始化密钥构造器
keyGenerator.Init(param);
//产生密钥对
AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
//获取公钥和密钥
AsymmetricKeyParameter publicKey = keyPair.Public;
AsymmetricKeyParameter privateKey = keyPair.Private; SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey); Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object(); byte[] publicInfoByte = asn1ObjectPublic.GetEncoded("UTF-8");
Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded("UTF-8"); RSAKEY item = new RSAKEY()
{
PublicKey = Convert.ToBase64String(publicInfoByte),
PrivateKey = Convert.ToBase64String(privateInfoByte)
};
return item;
}
private AsymmetricKeyParameter GetPublicKeyParameter(string keyBase64)
{
keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", "");
byte[] publicInfoByte = Convert.FromBase64String(keyBase64);
Asn1Object pubKeyObj = Asn1Object.FromByteArray(publicInfoByte);//这里也可以从流中读取,从本地导入
AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);
return pubKey;
} private AsymmetricKeyParameter GetPrivateKeyParameter(string keyBase64)
{
keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", "");
byte[] privateInfoByte = Convert.FromBase64String(keyBase64);
// Asn1Object priKeyObj = Asn1Object.FromByteArray(privateInfoByte);//这里也可以从流中读取,从本地导入
// PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
return priKey;
} /// <summary>
/// 私钥加密
/// </summary>
/// <param name="data">加密内容</param>
/// <param name="privateKey">私钥(Base64后的)</param>
/// <returns>返回Base64内容</returns>
public string EncryptByPrivateKey(string data, string privateKey)
{
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine()); //加密 try
{
engine.Init(true, GetPrivateKeyParameter(privateKey));
byte[] byteData = Encoding_UTF8.GetBytes(data);
var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Convert.ToBase64String(ResultData);
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// 私钥解密
/// </summary>
/// <param name="data">待解密的内容</param>
/// <param name="privateKey">私钥(Base64编码后的)</param>
/// <returns>返回明文</returns>
public string DecryptByPrivateKey(string data, string privateKey)
{
data = data.Replace("\r", "").Replace("\n", "").Replace(" ", "");
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine()); //解密
try
{
engine.Init(false, GetPrivateKeyParameter(privateKey));
byte[] byteData = Convert.FromBase64String(data);
var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Encoding_UTF8.GetString(ResultData);
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// 公钥加密
/// </summary>
/// <param name="data">加密内容</param>
/// <param name="publicKey">公钥(Base64编码后的)</param>
/// <returns>返回Base64内容</returns>
public string EncryptByPublicKey(string data, string publicKey)
{
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine()); //加密
try
{
engine.Init(true, GetPublicKeyParameter(publicKey));
byte[] byteData = Encoding_UTF8.GetBytes(data);
var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Convert.ToBase64String(ResultData);
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// 公钥解密
/// </summary>
/// <param name="data">待解密的内容</param>
/// <param name="publicKey">公钥(Base64编码后的)</param>
/// <returns>返回明文</returns>
public string DecryptByPublicKey(string data, string publicKey)
{
data = data.Replace("\r", "").Replace("\n", "").Replace(" ", "");
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine()); //解密
try
{
engine.Init(false, GetPublicKeyParameter(publicKey));
byte[] byteData = Convert.FromBase64String(data);
var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Encoding_UTF8.GetString(ResultData); }
catch (Exception ex)
{
throw ex;
}
}
}
}

Java和.Net互相使用RSA加密时的问题和处理方法的更多相关文章

  1. 电信级的RSA加密后的密码的破解方法

    一直以来,电信通过HTTP劫持推送广告的方式已经存在了很多年了,这种手段至今并未停止.这种手段月光博客曾经有多次曝光,见<电信级的网络弹出广告>.<获取了电信恶意弹出广告的罪证> ...

  2. Android MD5加密、RSA加密

    现在公司做金融项目,需要考虑安全加密方面的问题.感谢大牛同事(冯哥) ,给我很大的帮助. 考虑到安全优化,我们把秘钥.加密步骤放到native中.考虑用到的技术:(1 )jni,(2 )OpenSSL ...

  3. RSA 加密解密使用实例

    http://www.dtmao.cc/news_show_692109.shtml 本文不讨论RSA加密解密本身,只记录使用方法及遇到的坑,RSA原理及注意事项可在网上查找. 背景:公司的一个需求, ...

  4. C# Java间进行RSA加密解密交互(二)

    原文:C# Java间进行RSA加密解密交互(二) 接着前面一篇文章C# Java间进行RSA加密解密交互,继续探讨这个问题. 在前面,虽然已经实现了C# Java间进行RSA加密解密交互,但是还是与 ...

  5. java和php实现RSA加密互通-b

    java和PHP RSA加密实现互通 1:通过openssl 生成公钥和密钥文件(linux) (1)  生产私钥文件命令 openssl genrsa -out rsa_private_key.pe ...

  6. Java MD5加密与RSA加密

    区别: MD5加密: 加密时通过原字符串加密成另一串字符串 解密时需要原加密字符串进行重新加密比较两次加密结果是否一致 T=RSA加密: 加密时通过原字符串生成密钥对(公钥+私钥) 解密时通过公钥和私 ...

  7. Java使用RSA加密解密签名及校验

    RSA加密解密类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ...

  8. Java采用RSA加密及解密技术的有关Maven项目的配置流程:

    第一步: 获得RSA公钥私钥(秘钥格式:PKCS#8 ,测试使用的是无私钥密码的) 公钥: -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4G ...

  9. JAVA RSA加密AES加密

    RSA加密: import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.Cipher; imp ...

  10. Java & PHP & Javascript 通用 RSA 加密 解密 (长字符串)

    系统与系统的数据交互中,有些敏感数据是不能直接明文传输的,所以在发送数据之前要进行加密,在接收到数据时进行解密处理:然而由于系统与系统之间的开发语言不同. 本次需求是生成二维码是通过java生成,由p ...

随机推荐

  1. JAVAEE——JDK安装

    1.JDK下载 (1)jdk官网 1.输入下载地址:Oracle Software Downloads | Oracle 2.向下滑动,找到Developer Downloads后点击java 3.点 ...

  2. java使用正则表达式验证手机号和电话号码和邮箱号码的方法

    验证手机号 我国的手机号一般是以1开头,后面跟着10位数字.因此,可以用如下正则表达式: public static boolean isValidPhoneNumber(String phoneNu ...

  3. USB2.0 DP DM VBUS

    在USB 2.0中,设备成功枚举的标志可以通过观察 D+ (dp).D- (dm) 和 VBUS 引脚的电压波形来判断.以下是这些信号在USB 2.0枚举过程中常见的状态: VBUS (5V供电): ...

  4. Python | os.path.join() method

    Python中的os.path.join()方法可以连接一个或多个路径组件. 此方法将各个路径组成部分,与每个非空部分路径组成部分恰好用一个目录分隔符(" /")连接起来. 如果要 ...

  5. 28. 找出字符串中第一个匹配项的下标 Golang实现

    题目描述: 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始).如果 needle 不是 hay ...

  6. 简述 JavaScript脚本的执行原理?

    js 是一种动态 . 弱类型 . 基于原型的语言 ,通过浏览器可以直接执行: 当浏览器遇到 <script></script>标记时 , 会执行标记之间的js 代码:然后js ...

  7. kotlin更多语言结构——>解构声明

    解构声明 有时把一个对象 解构 成很多变量会很方便,例如: val (name, age) = person 这种语法称为 解构声明 .一个解构声明同时创建多个变量.我们已经声明了两个新变量:name ...

  8. day10-变量、常量、作用域及命名规范

    变量 变量是什么?就是可以变化的量! Java是一种强类型语言,每个变量都必须声明其类型. Java变量是程序中最基本的存储单元,其要素包括变量名.变量类型和作用域.   type varName [ ...

  9. KubeSphere 助力提升研发效能的应用实践分享

    作者:卢运强,主要从事 Java.Python 和 Golang 相关的开发工作.热爱学习和使用新技术:有着十分强烈的代码洁癖:喜欢重构代码,善于分析和解决问题.原文链接. 我司从 2022 年 6 ...

  10. 华为云云容器引擎CCE踩坑记

    前几天把在公司办公区机房的一部分业务系统迁移至华为云,在华为云上现有的kubernetes集群(云容器引擎CCE)中创建了一个命名空间,并启用了命名空间的网络隔离功能,在该命名空间中创建了一些pod- ...