很久以前的文章中,演示了如何对于.net和win32下面的delphi的RSA互操作性的实现,对于C#和JAVA之前的RSA加密解密也是很简单的,一般都采用了标准的规范,所以在互操作性方面是很方便的。之前也有博友私信请教这方面的问题,现在放出一个demo实现:
一、概述
算法:RSA/ECB/PKCS1Padding
RSA KEY:为了便于演示,使用http://www.cnblogs.com/midea0978/articles/768824.html中的Key
代码:C# & JAVA
二、JAVA平台
1
import org.junit.Test;
2
import sun.misc.BASE64Decoder;
3
import sun.misc.BASE64Encoder;
4
5
import javax.crypto.Cipher;
6
import java.io.IOException;
7
import java.math.BigInteger;
8
import java.security.KeyFactory;
9
import java.security.PrivateKey;
10
import java.security.PublicKey;
11
import java.security.spec.RSAPrivateKeySpec;
12
import java.security.spec.RSAPublicKeySpec;
13
14
/**
15
* 基于.net的PKCS1Padding加密信息的JAVA解密交互操作
16
* 参考:
http://www.cnblogs.com/midea0978/articles/768824.html
17
* User: midea0978
18
* Date: 11-12-10 上午10:51
19
*/
20
public
class RSATest {
21 String e = "65537";
22 String n = "123410773237385713572440712840019405878257600213906351775134402766524785605776353635515879438375969303333340691224323217379791619946464100287854264933660919378485000299257054039555887477610831829409144592603086784397675690934246422666689022312589317493002336070775714030955737435316659994026756956753416169929";
23 String d = "102299672961750099570264341757280532275542401837445663770632643616494888426681205847125069294737520917541038900032845310395266178574112466427178094767628391398378924953787043659322148498169017989730953803803890989295625028193153480552247210183981959942844345362118479513739632952091865360095551345350474614233";
24
25 @Test
26
public
void testDecrypt() {
27 BigInteger bn =
new BigInteger(n);
28 BigInteger be =
new BigInteger(e);
29 BigInteger bd =
new BigInteger(d);
30 RSAPublicKeySpec pub =
new RSAPublicKeySpec(bn, be);
31 RSAPrivateKeySpec prv =
new RSAPrivateKeySpec(bn, bd);
32
try {
33 KeyFactory kf = KeyFactory.getInstance("RSA");
34 PublicKey pubkey = kf.generatePublic(pub);
35 PrivateKey prvkey = kf.generatePrivate(prv);
36 Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
37
//
加密
38 rsa.init(Cipher.ENCRYPT_MODE, pubkey);
39 String txt = "Welcome,RSA!from 博客园";
40
byte[] encdata = rsa.doFinal(txt.getBytes());
41 System.out.printf("RSA加密:\n明文:%s\n密文:%s\n", txt, convertToBase64(encdata));
42
//
解密
43 rsa.init(Cipher.DECRYPT_MODE, prvkey);
44 rsa.update(encdata);
45
byte[] res = rsa.doFinal();
46 System.out.printf("解密:%s",
new String(res));
47 }
catch (Exception e1) {
48 e1.printStackTrace();
49 }
50 }
51
52
public
byte[] convertFromBase64(String s)
throws IOException {
53 s = s.replaceAll("\\\\n", "\n");
54 BASE64Decoder decoder =
new BASE64Decoder();
55
return decoder.decodeBuffer(s);
56 }
57
58
public String convertToBase64(
byte[] data) {
59 BASE64Encoder encoder =
new BASE64Encoder();
60
return encoder.encode(data);
61 }
62
63
64 }
运行结果:
RSA加密:
明文:Welcome,RSA!from 博客园
密文:E3F+Qwyk8MJkHv7zEOb4Fdg0CX4pQOKghyOmMew8jPDUbxNJhDSlV/aS5nnVuiEtkWU1BmCrPSEi
swhuEjC7eRJnq5pEkyf0GILHFNkuoqD1o4FjKnl/oTXg83wn5JDgi5Bog5lJM8YcQcExEMsH9IF+
gbeq6rWYrbb4Qj2oM8c=
解密:Welcome,RSA!from 博客园
三:C#解密
将上面JAVA加密的信息加入到程序中解密:
1
using System.Text.RegularExpressions;
2
using System.Text;
3
using System.IO;
4
using System.Net;
5
using System.Xml;
6
using System.Runtime.InteropServices;
7
using System;
8
using System.Security;
9
using System.Security.Cryptography;
10
public
class RSATestForJava
11 {
12
private String p,q,e,n,d,dp,dq,crt;
13
private RSAParameters param;
14
public
void Init(){
15 p=
"
12794390226544301614076650435602993036558056678553112540698297249963365434628505393116653422818365344228379828231764392521731584684435248093787027949139091
";
16 q=
"
9645694015283940797244851561543569992525098416055322825220116046655435860727361740896753161534492415500799272063647633894112205918420307541634544631799219
";
17 e=
"
65537
";
18 n=
"
123410773237385713572440712840019405878257600213906351775134402766524785605776353635515879438375969303333340691224323217379791619946464100287854264933660919378485000299257054039555887477610831829409144592603086784397675690934246422666689022312589317493002336070775714030955737435316659994026756956753416169929
";
19 d=
"
102299672961750099570264341757280532275542401837445663770632643616494888426681205847125069294737520917541038900032845310395266178574112466427178094767628391398378924953787043659322148498169017989730953803803890989295625028193153480552247210183981959942844345362118479513739632952091865360095551345350474614233
";
20 dp=
"
1529969882744521289493243655703200580244831014386083326692594344385048063096931454992679141166478923397741927672190328275520857365639547725880173612423563
";
21 dq=
"
769453717928871362558494956494038236735297839680443531596667023084892788499361386413907037681040120057954721673997128797449053397950796768659923391901465
";
22 crt=
"
12583540851660819630796910273258143748946857763306703439274571717196507402536398234616014735603915981141807543055250658251670340810611251684169356826070785
";
23
24 param=
new RSAParameters();
25
byte[] bdata=GetBytes(e);
26 param.Exponent=bdata;
27 param.P=GetBytes(p);
28 param.Q=GetBytes(q);
29 param.Modulus=GetBytes(n);
30 param.D=GetBytes(d);
31 param.DP=GetBytes(dp);
32 param.DQ=GetBytes(dq);
33 param.InverseQ=GetBytes(crt);
34 }
35
public
void DoTest(){
36 RSACryptoServiceProvider rsa =
new RSACryptoServiceProvider();
37 rsa.ImportParameters(param);
38 String edata=
"
E3F+Qwyk8MJkHv7zEOb4Fdg0CX4pQOKghyOmMew8jPDUbxNJhDSlV/aS5nnVuiEtkWU1BmCrPSEi
";
39 edata+=
"
swhuEjC7eRJnq5pEkyf0GILHFNkuoqD1o4FjKnl/oTXg83wn5JDgi5Bog5lJM8YcQcExEMsH9IF+
";
40 edata+=
"
gbeq6rWYrbb4Qj2oM8c=
";
41
//
解密JAVA加密的数据
42 Byte[] encdata=Convert.FromBase64String(edata);
43
byte[] dedata=rsa.Decrypt(encdata,
false);
44 Console.WriteLine(
"
\n解密JAVA加密的数据:
"+Encoding.Default.GetString(dedata));
45 }
46
public
static
void Main(String[] args)
47 {
48 RSATestForJava obj=
new RSATestForJava();
49 obj.Init();
50 obj.DoTest();
51 }
52
public
static
byte[] GetBytes(String num){
53 BigInteger n=
new BigInteger(num,
10);
54 String s=n.ToString(
2);
55
if(s.Length%
8>
0){
56 s=
new String(
'
0
',
8-s.Length%
8)+s;
57 }
58
byte[] data=
new
byte[s.Length/
8];
59 String ocetstr;
60
for(
int i=
0;i<data.Length;i++){
61 ocetstr=s.Substring(
8*i,
8);
62 data[i]=Convert.ToByte(ocetstr ,
2 ) ;
63 }
64
return data;
65 }
66
67
public String ConvByteArrayToHex(
byte[] data){
68 String s=
"";
69
for(
int i=
0;i<data.Length;i++){
70 s+=Convert.ToString(data[i],
16);
71 }
72
return s.ToUpper();
73 }
74
75
76 }
编译运行结果:
D:\allproject\rsa.net>csc RSATestForJava.cs BigInteger.cs
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.3053
for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.
D:\allproject\rsa.net>RSATestForJava
解密JAVA加密的数据:Welcome,RSA!from 博客园
D:\allproject\rsa.net>
C#代码下载:RSAtestForJava.rar
达成交互效果!