.NET和java的RSA互通,仅此而已
.NET和java的RSA互通,仅此而已
在开始这篇文章之前,先请读者朋友阅读老唐的这两篇文章:
1、Java与.Net环境下RSA加密解密交互不成功的问题解决
2、Java与.Net环境下RSA加密解密交互不成功的问题解决【续】
和我的这篇文章
前面老唐的两篇文章中提到,要想实现.NET和Java的RSA互通,只能抛弃.NET现有的加密算法,而是利用http://www.codeproject.com/csharp/biginteger.asp 项目中的BigInteger类(.NET Framework4中已增加了这个类的实现,在System.Numberic命名空间中),这个BigInteger类实际上就是仿照着java的BigInteger类来写的。
利用这个类的确可以很好的实现RSA的加解密,比如,在.NET端,构建一个公钥对应的BigInteger e、一个模对应的BigInteger n和一个明文对应的BigInteger m,然后执行语句BigInteger c=m.modPow(e,n),便可以实现加密操作,密文为c,这样的加密是标准加密,没有附加任何填充算法的加密。
老唐的文章中说,不能互通是因为加密标准不一样,导致一方加密而另一方不能解密,其实不然,.NET采用的加密标准是PKCS1Padding(或OAEPPadding——只支持XP以上版本),这也是我在前面一篇文章中提到的一种填充算法,而java同样支持这一填充标准,既然可以遵循统一的标准,那么.NET和java的RSA互通,无需添加任何新代码便可以轻松实现!
请看下面的示例(.NET端加密,Java端解密):
Java端代码:
- import java.math.BigInteger;
- import java.util.Scanner;
- import java.security.KeyFactory;
- import java.security.PrivateKey;
- import java.security.KeyPair;
- import java.security.KeyPairGenerator;
- import java.security.PublicKey;
- import java.security.interfaces.RSAPrivateKey;
- import java.security.interfaces.RSAPublicKey;
- import java.security.spec.RSAPublicKeySpec;
- import javax.crypto.Cipher;
- import sun.misc.*;
- public class RsaKey {
- public static void main(String[] args) throws Exception {
- //生成公私钥对
- KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
- keyPairGen.initialize(1024);
- KeyPair keyPair = keyPairGen.generateKeyPair();
- PublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
- PrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
- //将公钥和模进行Base64编码
- KeyFactory keyFactory = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec publicSpec= keyFactory.getKeySpec(publicKey,RSAPublicKeySpec.class);
- BigInteger modulus = publicSpec.getModulus();
- BigInteger exponent=publicSpec.getPublicExponent();
- byte[] ary_m=modulus.toByteArray();//注意:对公钥和模进行Base64编码时,不是对BigInteger对应的字符串编码,而是对其内部 的字节数组进行编码
- byte[] ary_e=exponent.toByteArray();
- String str_m;
- String str_e;
- if(ary_m[0]==0 && ary_m.length==129)//判断数组首元素是否为0,若是,则将其删除,保证模的位数是128
- {
- byte[] temp=new byte[ary_m.length-1];
- for(int i=1;i<ary_m.length;i++)
- {
- temp[i-1]=ary_m[i];
- }
- str_m=(new BASE64Encoder()).encodeBuffer(temp);
- }
- else
- {
- str_m=(new BASE64Encoder()).encodeBuffer(ary_m);
- }
- str_e=(new BASE64Encoder()).encodeBuffer(ary_e);
- System.out.println("公钥为:"+str_e);
- System.out.println("模为:"+str_m);
- System.out.println("运行.NET程序,用所提供的公钥和模进行加密,然后将加密结果输入本程序进行解密:");
- Scanner sc=new Scanner(System.in);
- String str_en="";
- String st="";
- while(!(st=sc.nextLine()).equals(""))
- {
- str_en+=st;
- }
- byte[] ary_en=(new BASE64Decoder()).decodeBuffer(str_en);
- //解密
- //注意Cipher初始化时的参数“RSA/ECB/PKCS1Padding”,代表和.NET用相同的填充算法,如果是标准RSA加密,则参数为“RSA”
- Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- cipher.init(Cipher.DECRYPT_MODE, privateKey);
- byte[] deBytes = cipher.doFinal(ary_en);
- String s = new String(deBytes );
- System.out.println("解密结果为:" + s);
- }
- }
Java端演示截图
.NET端代码:
- static void Main(string[] args)
- {
- try
- {
- RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- RSAParameters para = new RSAParameters();
- //加密
- Console.WriteLine("请输入公钥");
- string publicKey = Console.ReadLine();
- Console.WriteLine("请输入模:");
- string modulus = Console.ReadLine();
- while(true)
- {
- string s = Console.ReadLine();
- if (s == "")
- {
- break;
- }
- else
- {
- modulus += s;
- }
- }
- Console.WriteLine("请输入明文:");
- string m = Console.ReadLine();
- para.Exponent = Convert.FromBase64String(publicKey);
- para.Modulus = Convert.FromBase64String(modulus);
- rsa.ImportParameters(para);
- byte[] enBytes = rsa.Encrypt(UTF8Encoding.UTF8.GetBytes(m),false);
- Console.WriteLine("密文为:"+Convert.ToBase64String(enBytes));
- Console.ReadLine();
- }
- catch(Exception ex)
- {
- Console.WriteLine(ex.Message);
- Console.ReadLine();
- }
.NET端演示截图:
接下来的示例是(java端加密,.NET端解密):
.net端代码:
- static void Main(string[] args)
- {
- try
- {
- RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- RSAParameters para = rsa.ExportParameters(true);
- //加¨®密¨¹
- Console.WriteLine("公?钥?为a:êo"+ Convert.ToBase64String(para.Exponent));
- Console.WriteLine("模¡ê为a:êo" + Convert.ToBase64String(para.Modulus));
- Console.WriteLine("请?输º?入¨?密¨¹文?");
- string enStr = Console.ReadLine();
- while(true)
- {
- string s = Console.ReadLine();
- if (s == "")
- {
- break;
- }
- else
- {
- enStr += s;
- }
- }
- byte[] deBytes = rsa.Decrypt(Convert.FromBase64String(enStr),false);
- Console.WriteLine("明¡Â文?为a:êo"+UTF8Encoding.UTF8.GetString(deBytes));
- Console.ReadLine();
- }
- catch(Exception ex)
- {
- Console.WriteLine(ex.Message);
- Console.ReadLine();
- }
- }
Java端代码:
- public static void main(String[] args) throws Exception {
- Scanner sc=new Scanner(System.in);
- //获取公钥、模及明文的字符串
- System.out.println("请输入公钥:");
- String str_exponent=sc.nextLine();
- System.out.println("请输入模:");
- String str_modulus="";
- String st="";
- while(!(st=sc.nextLine()).equals(""))
- {
- str_modulus+=st;
- }
- System.out.println("请输入明文:");
- String str_m=sc.nextLine();
- //创建公钥
- byte[] ary_exponent=(new BASE64Decoder()).decodeBuffer(str_exponent);
- byte[] ary_modulus=(new BASE64Decoder()).decodeBuffer(str_modulus);
- //注意构造函数,调用时指明正负值,1代表正值,否则报错
- BigInteger big_exponent = new BigInteger(1,ary_exponent);
- BigInteger big_modulus = new BigInteger(1,ary_modulus);
- RSAPublicKeySpec keyspec=new RSAPublicKeySpec(big_modulus,big_exponent);
- KeyFactory keyfac=KeyFactory.getInstance("RSA");
- PublicKey publicKey=keyfac.generatePublic(keyspec);
- //进行加密
- Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- cipher.init(Cipher.ENCRYPT_MODE, publicKey);
- byte[] enBytes = cipher.doFinal(str_m.getBytes());
- String s = (new BASE64Encoder()).encodeBuffer(enBytes);
- System.out.println("加密结果为:" + s);
- }
.NET和java的RSA互通,仅此而已的更多相关文章
- Java & PHP RSA 互通密钥、签名、验签、加密、解密
RSA加密算法是一种非对称加密算法.在公开密钥加密和电子商业中RSA被广泛使用.RSA是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Le ...
- php与JAVA的RSA加密互通
Java 版本RSA 进行加密解密 在网上查询了好几天,最终找到解决方案,网络上都是通过Cipher.getInstance("RSA"); 而改成Cipher.getInstan ...
- Java加密算法 RSA
Java加密算法 RSA 2015-06-06 08:44 511人阅读 评论(0) 收藏 举报 分类: JAVA(57) 公钥加密也称为非对称加密.速度慢.加密和解密的钥匙不相同,某一个人持有私 ...
- Java前端Rsa公钥加密,后端Rsa私钥解密(目前还不支持中文加密解密,其他都行)
Base64工具类,可以让rsa编码的乱码变成一串字符序列 package com.utils; import java.io.ByteArrayInputStream; import java.io ...
- Java前端Rsa公钥加密,后端Rsa私钥解密(支持字符和中文)
Base64工具类,可以让rsa编码的乱码变成一串字符序列 package com.utils; import java.io.ByteArrayInputStream; import java.io ...
- JAVA实现RSA加密,非对称加密算法
RSA.java package org.icesnow.jeasywx.util.security; import java.security.Key; import java.security.K ...
- JAVA实现RSA加密解密 非对称算法
首先RSA是一个非对称的加密算法.所以在使用该算法加密解密之前,必须先行生成密钥对.包含公钥和私钥 JDK中提供了生成密钥对的类KeyPairGenerator,实比例如以下: public stat ...
- 【转】 Java 进行 RSA 加解密时不得不考虑到的那些事儿
[转] Java 进行 RSA 加解密时不得不考虑到的那些事儿 1. 加密的系统不要具备解密的功能,否则 RSA 可能不太合适 公钥加密,私钥解密.加密的系统和解密的系统分开部署,加密的系统不应该同时 ...
- java生成RSA公私钥字符串,简单易懂
java生成RSA公私钥字符串,简单易懂 解决方法: 1.下载bcprov-jdk16-140.jar包,参考:http://www.yayihouse.com/yayishuwu/chapter ...
随机推荐
- 【题解】【DP】【Leetcode】Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- apt-get 的常用使用说明
API神命令: apt-get -h >>help.txt apt 1.0.10.2ubuntu1,用于 amd64 体系结构,编译于 Oct 5 2015 15:55:05用法: apt ...
- ubuntu 挂载优盘
不知道为什么重装一次ubuntu后无法自动挂载优盘,只好手动: sudo mount /dev/sdb1 /media/YCC_FD/ 注意,这里优盘是sdb 而非sda 查找自己优盘在什么地方,可以 ...
- ueditor上传图片到七牛云存储(form api,java)
转:http://my.oschina.net/duoduo3369/blog/174655 ueditor上传图片到七牛云存储 ueditor结合七牛传图片 七牛的试炼 开发前的准备与注意事项说明 ...
- windows 任务栏图标宽度固定
这个需要修改注册表. win+r regedit ->enter 找到以下项 HKEY_CURRENT_USER-Control Panel-Desktop-WindowsMetrics 新建字 ...
- 快排算法(C++版)
#include <iostream> using namespace std; /** Quick Sort * * split: cmp && swap * left ...
- leetcode 121. Best Time to Buy and Sell Stock ----- java
Say you have an array for which the ith element is the price of a given stock on day i. If you were ...
- Visual Studio 2012 update3 安装后的问题及解决
安装之后可能遇到的问题: 安装完时,打开Help Viewer时,出现了一个错误提示:”a content file required by the help viewer is missing or ...
- VIM进阶学习之几种模式和按键映射
Map是Vim强大的一个重要原因,可以自定义各种快捷键,用起来自然得心应手. vim里最基本的map用法也就是 :map c a 这里把c映射成了a,在map生效的情况下,按下c就等同于按下了a 当然 ...
- 论文笔记之:Heterogeneous Image Features Integration via Multi-Modal Semi-Supervised Learning Model
Heterogeneous Image Features Integration via Multi-Modal Semi-Supervised Learning Model ICCV 2013 本文 ...