PS:好久没写博了,最近在考虑以后的事情,而且手上杂事也比较多,终于得空来写两篇。
 
 
由于公司同时使用.NET和JAVA,而且各个服务集使用接口来进行通信,因此某些例如清算系统、收银台之类的安全性比较高的系统会使用RSA进行加密。因此会涉及到密钥的转换。所以大概看了下C#的秘钥跟JAVA的密钥区别。
RSA对于程序本身是没有区别的,其格式都是相同的。对于不同的程序来说,存储使用的语法(包装的类)会有所不同。
RSA语法和语法标准有很多,大的类型大概分为ASN.1、PKCS、X.509。

RSA语法介绍

ASN.1、PKCS是最初的,也是最主要的RSA公钥和私钥的语法标准,被RSA Lab所维护。
ASN.1、PKCS#1都定义了公钥和私钥的类型——序列化的数字。为了下一个层次的抽象(适当的包装),现在一般使用的组合是:PKCS#8的私钥,X.509的公钥 。
PKCS语法主要用于私钥,其内部标准目前有10种。目前JAVA普遍使用的是PKCS#8,用作私钥格式。
X.509语法主要用于公钥,广泛使用于web浏览器和SLL。 
3种语法标准的公私钥可以实现相互转化,其核心为ASN1语法中的整数值(modulus,PublicExponent,privateExponent ),其余的数值都可以经过计算后得出。
 
.NET使用的是标准的RSA格式,然后将其中的数字base64编码后,生成XML进行存储。
java中使用的是PKCS#8,、X.509的公私钥语法,存储的都是相应的JAVA类自动生成的base64字符串。
由于存储格式的区别,在相互转换、读取的时候,需要理解RSA相关的知识,才能正确使用类来转换。
 

C#转JAVA

C#中的公私钥使用XML字符串进行存储,读取时直接读入字符串即可。
由于C#使用的是标准的RSA格式,因此JAVA的RSAPublicKeySpec、RSAPrivateKeySpec配置类的核心参数(modulus,PublicExponent,privateExponent )都可以从对应XML中的节点值(Modulus-modulus 、Exponent-PublicExponent 、D-privateExponent )base64解码后获取。然后将其传入JAVA配置类中,然后根据配置类生成相应的RSA公私钥。
 byte[] m = Base64.decodeBase64("mX/9zl8rflH5pLaP5P1Qd/9wXwNBSx7OpLlYDnGr7wD0njiDfPSUkgf9oF5NcvZwl24qdJ1SLmrgUtnr+yeXBNZNKaan1xXKISHdlHvbW5G8nJCJW6CuaHMkVw3Y7kwaIIlUdv09vxfjj0AoabttjbtF1kqETzbQ6fK3EN6sY5U=");
byte[] e = Base64.decodeBase64("AQAB");
BigInteger b1 = new BigInteger(1, m);
BigInteger b2 = new BigInteger(1, e);
byte[] m1 = Base64.decodeBase64("3RgqP5YOYUXft8YOlDphyaCoof27MSfTD2eVCFVXB5hatrls1fSUcmUuWuGV970sS6KQZZtyWHQ5970sCzKFlq82He8Uoe0JM3axBvd6PbSGjulUJr62qNW5hgkIEfxSRYl8AQsbbusFtks4obfepsfE02cLmmZepnZAdIOWifE=");
byte[] e1 = Base64.decodeBase64("QcSZdLbHakolxX4GAjPnuNmwsBdRIsss7o0qeQMh02GPwoEgDfkmW20bv+8Q9FPypEEkYQU/m25ffAFq453QvLegYYi8OvWN+dvgchQRdeb22d+s6xYGGN9DRcPFRE48INde8FBHf/lzVgToV75h1H7g+jB4hLmLeuIuHsB43/0=");
BigInteger b11 = new BigInteger(1, m1);
BigInteger b21 = new BigInteger(1, e1);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(b11, b21);
RSAPrivateKey priKey = (RSAPrivateKey) keyFactory.generatePrivate(priKeySpec);

JAVA转C#

JAVA中的公私钥使用base64进行存储,解码成字节数组后,首先需要生成相应的配置对象(PKCS#8,、X.509 ),根据配置对象生成RSA公私钥。
私钥
C#使用的是标准的RSA格式,PKCS#1语法中包含了标准RSA格式私钥中的所有整数值。配置对象需要生成PKCS#1语法的RSA对象(RSAPrivateCrtKey),获取对象属性,自行构造私钥XML。
 private static String getRSAPrivateKeyAsNetFormat(byte[] encodedPrivateKey) {
try {
StringBuffer buff = new StringBuffer(1024);
PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(pvkKeySpec);
buff.append("<RSAKeyValue>");
buff.append("<Modulus>" + encodeBase64(removeMSZero(pvkKey.getModulus().toByteArray())) + "</Modulus>");
buff.append("<Exponent>" + encodeBase64(removeMSZero(pvkKey.getPublicExponent()toByteArray())) + "</Exponent>");
buff.append("<P>" + encodeBase64(removeMSZero(pvkKey.getPrimeP().toByteArray())) + "</P>");
buff.append("<Q>" + encodeBase64(removeMSZero(pvkKey.getPrimeQ().toByteArray())) + "</Q>");
buff.append("<DP>" + encodeBase64(removeMSZero(pvkKey.getPrimeExponentP().toByteArray())) + "</DP>");
buff.append("<DQ>" + encodeBase64(removeMSZero(pvkKey.getPrimeExponentQ().toByteArray())) + "</DQ>");
buff.append("<InverseQ>" + encodeBase64(removeMSZero(pvkKey.getCrtCoefficient().toByteArray())) + "</InverseQ>");
buff.append("<D>" + encodeBase64(removeMSZero(pvkKey.getPrivateExponent().toByteArray())) + "</D>");
buff.append("</RSAKeyValue>");
return buff.toString();
} catch (Exception e) {
System.err.println(e);
return null;
}
}
公钥
公钥跟私钥生成步骤相同,配置对象生成标准的RSA对象(RSAPublicKey)。
 private static String getRSAPublicKeyAsNetFormat(byte[] encodedPublicKey) {
try {
StringBuffer buff = new StringBuffer(1024);
//Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey pukKey = (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(encodedPublicKey));
buff.append("<RSAKeyValue>");
buff.append("<Modulus>" + encodeBase64(removeMSZero(pukKey.getModulus().toByteArray())) + "</Modulus>");
buff.append("<Exponent>" + encodeBase64(removeMSZero(pukKey.getPublicExponent().toByteArray())) + "</Exponent>");
buff.append("</RSAKeyValue>");
return buff.toString();
} catch (Exception e) {
System.err.println(e);
return null;
}
}

RSA密钥——JAVA与C#的区别和联系的更多相关文章

  1. RSA密钥,JAVA与.NET之间转换

    最近在做银联的一个接口,用到RSA签名,悲剧来了,.net用的RSA密钥格式和JAVA用的不一样 .net为XML格式 <RSAKeyValue><Modulus>53Knuj ...

  2. C#和JAVA的RSA密钥、公钥转换

    C#的秘钥跟JAVA的密钥区别   RSA对于程序本身是没有区别的,其格式都是相同的.对于不同的程序来说,存储使用的语法(包装的类)会有所不同. RSA语法和语法标准有很多,大的类型大概分为ASN.1 ...

  3. RSA密钥之C#格式与Java格式转换

    前言 最近由于项目需求,服务端由c#编写,客户端由java编写.通信数据使用RSA非对称加密.但是java和c#生成的密钥格式是不一样的,所以需要转换格式才可以正常使用.网上搜到使用java进行格式转 ...

  4. JAVA,NET RSA密钥格式转换

    JAVA和NET RSA密钥格式相互转换(公钥,私钥) 做了一个小项目遇到java和.net非对称加密问题,java的公钥和私钥就直接是一个字符串的形式展示的,但是.net是以xml简单包裹形式展示的 ...

  5. Java与.NET兼容的RSA密钥持久化方法

    默认情况下,.NET生成的RSA密钥对可以用XML或字节流来保存,而JAVA中生成的RSA密钥对只能用字节流来保存.而它们的字节流格式不同,就导致Java中生成的RSA密钥对不能在.NET中使用,而. ...

  6. .NET Core RSA密钥的xml、pkcs1、pkcs8格式转换和JavaScript、Java等语言进行对接

    众所周知在.NET下的RSA类所生成的密钥为Xml格式,而其他语言比如java一般使用pkcs8格式的密钥,JavaScript一般使用pkcs1格式.我们在开发过程中很可能遇到需要与其他语言开发的a ...

  7. .NET与JAVA RSA密钥格式转换

    一.该篇内容用于记录.net和Java之间,RSA公密钥的转换 using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; ...

  8. RSA密钥的跨平台通用

    RSA使用public key加密,用private key解密(签名相反,使用private key签名,用public key验证签名).比如我跟合作方D之间的数据传输,我使用D提供给我的publ ...

  9. [转帖]RSA算法与DSA算法的区别

    RSA算法与DSA算法的区别 https://cloud.tencent.com/developer/news/254061 文章来源:企鹅号 - SuperFullStack 本文译自:StackE ...

随机推荐

  1. 【css3】如何自定义 placeholder 文本颜色

    昨天写了一篇基于 jquery 实现 ie 浏览器兼容 placeholder 效果,具体内容点击传送门.不过还是有点小瑕疵,就是不能设置 placeholder 文本颜色.本文主要介绍利用 css ...

  2. android 中handler的用法分析 (二)

    .Looper 的构造方法是私有的,不能在package外面直接初始化.一般通过Looper.prepare()初始化.Looper.myLooper()获取.2.Looper 中的静态变量 Thre ...

  3. 解决linux下主机名变bogon的问题

    早上起来发现 linux主机名变为bogon bogon是指那些不该出现在internet路由表中的地址吧这些地址应该包括:1,私有地址如10,172.16-32,192.168.....2,还未正式 ...

  4. <img> to image_tag

    <img src="clean_wave.jpg?" alt="Clean_wave"><%= image_tag("clean_w ...

  5. JSP Servlet性能分析

    JSP Servlet性能分析:http://www.docin.com/p-757790851.html

  6. CSS3实现旋转的太极图(二):只用1个DIV

    效果预览:   PS: 1.昨天用3个DIV实现了太极图(点击查看),,今天试着用1个Div来做. 2.公司刚忙过双10周年庆,最近空闲下来,闲着也是闲着,总得写点东西吧. 3.高手莫喷,小弟仅仅是没 ...

  7. 配置算法(第4版)的Java编译环境

    1. 下载 1.1 JDK http://www.oracle.com/technetwork/java/javase/downloads/index.html选择“Windows x64 180.5 ...

  8. 所有博客已经迁移到个人空间 blog.scjia.cc

    所有博客已经迁移到个人空间 blog.scjia.cc

  9. [C++] memset 和sizeof 的使用注意

    因为使用C++写小题目时经常需要清除数组,这里记录下Memset函数的sizeof运算符的使用注意. memset的特点是:将给定地址后连续的内存(包括给定地址),逐个byte初始化为参数中指明的值. ...

  10. 【转】ORATOP工具使用说明

    文章转自:http://lintzyuan.blogspot.jp/2014/07/oratop.html ORATOP   前言:隨著PC Server的規格及速度愈來愈快,大多數的公司摒棄大型主機 ...