java rsa私钥加密_JAVA RSA私钥 加密(签名) 对应 C# RSA私钥 加密(签名)

本文介绍了在JAVA和C#之间使用RSA非对称加密算法进行数据加解密时遇到的问题及解决方案。主要讨论了JAVA需要PKCS8格式的私钥,而C#需要PKCS1格式的私钥,并提供了转换方法。通过示例代码展示了JAVA和C#中如何使用私钥进行数据签名和验证,包括签名生成、私钥加载以及二进制到十六进制的转换过程。
摘要由CSDN通过智能技术生成

非对称密钥RSA算法加解密在C#和Java之间交互的问题,这两天看了很多其他人写的文章,碰到了几个问题,最终解决问题。

参考地址:http://xw-z1985.iteye.com/blog/1837376

需求目的:完成c#请求端RSA加密(签名)问题,客户端采用C#开发,服务器端采用Java开发。服务器端给客户端提供私钥,进行数据加密(签名),客户端加密(签名)后提数据提交给服务器,服务器用公钥对数据解密,进行验证。

解决过程碰到的问题:

1.JAVA 需要的 RSA私钥 格式和 C# 需要的 RSA私钥 不一致。

JAVA 需要是 PKCS8格式私钥:

-----BEGIN PRIVATE KEY-----MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOwuOHH/OIRE+0ifmEPYGuhYRTyKdd6VLFIsNqy/SO5xZitHfA7xEymJKnpEUGgDJKr5zbFbytnWs5Jj

gen6TXkUh9LG/fhPGGHdUVB42pAHv5yzoyEaOnJxBAxd6UstoWTaEgbT6GUbzMr/Az25zuxw7c+skAlnUETVE5GL3tD7AgMBAAECgYEAxdNZODMctb3J9OSo93rV3vPA

2prna87rVtDt4vg+MGsPtwSjZyiKcmoQCGWcK+MmHYgrwHkwihKKSv3KXZ9or3xQ

2wNZGuTHLymWEzqfEfVb0igvxbe85EGwsaN3qSK62CK8vok/Bi+fZVa3UNCn0WFs

lUS0qn+K3SECM9I1iwECQQD+2Pl2AJGQs2bRXSsnJk0FIwjpqdpGZFPlAUYaXkuT

MqpwefP/bwwiuWqq9QIt2vAAKgy5T16tpPBcGpT6cvxBAkEA7T+i1gVwrXcozTuT

9oCwkF2MGBaXkv3mN9H/Pfy/oIhTsgiDxX8t+0KapAEQogvCuAOq19JvGw5e91H2

g0suOwJAJOMnCIuAhl9RTJCdxGbo0wuFKL0rGPFAq28JxJtNeRrmTK16QcjDCuun

ouMf059TCdMMUG5Kl/u9xrcaRT4LgQJAZPiUYOnnzqvMHayhiGO0wXxOx2G2GMUe

Wdtx+fu7wqLCnB6rlj5OX4U1M1+QqKbAtHg7Gadhye4P1Mp5U9+HSQJBANLVzcCX

yAX2D12UPTPkhcNRaCRXFp3aJGMxI4iluUC+ukAdiapohqZ7vMQyWRq/tDyiwjir

qMcg/AJIuQWmPyc=

-----END PRIVATE KEY-----

C# 需要的是 PKCS1 格式私钥:

-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQDsLjhx/ziERPtIn5hD2BroWEU8inXelSxSLDasv0jucWYrR3wO

8RMpiSp6RFBoAySq+c2xW8rZ1rOSY4Hp+k15FIfSxv34Txhh3VFQeNqQB7+cs6Mh

GjpycQQMXelLLaFk2hIG0+hlG8zK/wM9uc7scO3PrJAJZ1BE1RORi97Q+wIDAQAB

AoGBAMXTWTgzHLW9yfTkqPd61d7zwNqa52vO61bQ7eL4PjBrD7cEo2coinJqEAhl

nCvjJh2IK8B5MIoSikr9yl2faK98UNsDWRrkxy8plhM6nxH1W9IoL8W3vORBsLGj

d6kiutgivL6JPwYvn2VWt1DQp9FhbJVEtKp/it0hAjPSNYsBAkEA/tj5dgCRkLNm

0V0rJyZNBSMI6anaRmRT5QFGGl5LkzKqcHnz/28MIrlqqvUCLdrwACoMuU9eraTw

XBqU+nL8QQJBAO0/otYFcK13KM07k/aAsJBdjBgWl5L95jfR/z38v6CIU7IIg8V/LftCmqQBEKILwrgDqtfSbxsOXvdR9oNLLjsCQCTjJwiLgIZfUUyQncRm6NMLhSi9

KxjxQKtvCcSbTXka5kytekHIwwrrp6LjH9OfUwnTDFBuSpf7vca3GkU+C4ECQGT4

lGDp586rzB2soYhjtMF8TsdhthjFHlnbcfn7u8Kiwpweq5Y+Tl+FNTNfkKimwLR4

OxmnYcnuD9TKeVPfh0kCQQDS1c3Al8gF9g9dlD0z5IXDUWgkVxad2iRjMSOIpblA

vrpAHYmqaIame7zEMlkav7Q8osI4q6jHIPwCSLkFpj8n-----END RSA PRIVATE KEY-----

2.私钥格式之间的转换问题

转换参考地址: http://blog.csdn.net/hanzengyi/article/details/78029104

java 代码 , 注意这里的私钥:是Pem私钥文件中去除头(-----BEGIN PRIVATE KEY-----)和尾(-----END PRIVATE KEY-----)以及换行符后的字符串

1    /**

2 * @data: 待加密的字符串3 * @privateKey: 私钥4 */

5 public static String sign(byte[] data, String privateKey) throwsException {6

7 byte[] keyBytes = newBASE64Decoder().decodeBuffer(privateKey);8 PKCS8EncodedKeySpec pkcs8KeySpec = newPKCS8EncodedKeySpec(keyBytes);9

10 KeyFactory keyFactory = KeyFactory.getInstance("RSA");11

12 PrivateKey priKey =keyFactory.generatePrivate(pkcs8KeySpec);13

14 Signature signature = Signature.getInstance("SHA1withRSA");15 signature.initSign(priKey);16 signature.update(data);17

18 returnbyte2hex(signature.sign());19 }

c# 代码,注意这里的私钥:是Pem私钥文件中去除头(-----BEGIN RSA PRIVATE KEY-----)和尾(-----END RSA PRIVATE KEY-----)以及换行符后的字符串

1      ///

2      ///签名3      ///

4      /// 待加密的字符串

5      /// 私钥

6      ///

7      public static string Sign(string data, stringprivateKey)8 {9 RSACryptoServiceProvider rsaCsp =LoadCertificate(privateKey);10 byte[] dataBytes =Encoding.UTF8.GetBytes(data);11 byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");12 returnHex_2To16(signatureBytes);13 }14

15 private static RSACryptoServiceProvider LoadCertificate(stringprivateKey)16 {17 byte[] res = res =Convert.FromBase64String(privateKey);18 try

19 {20 RSACryptoServiceProvider rsa =DecodeRSAPrivateKey(res);21 returnrsa;22 }23 catch(Exception ex)24 {25 }26 return null;27 }28

29 private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)30 {31 byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;32

33 //--------- Set up stream to decode the asn.1 encoded RSA private key ------

34 MemoryStream mem = newMemoryStream(privkey);35 BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading

36 byte bt = 0;37 ushort twobytes = 0;38 int elems = 0;39 try

40 {41 twobytes =binr.ReadUInt16();42 if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)

43 binr.ReadByte(); //advance 1 byte

44 else if (twobytes == 0x8230)45 binr.ReadInt16(); //advance 2 bytes

46 else

47 return null;48

49 twobytes =binr.ReadUInt16();50 if (twobytes != 0x0102) //version number

51 return null;52 bt =binr.ReadByte();53 if (bt != 0x00)54 return null;55

56

57 //------ all private key components are Integer sequences ----

58 elems =GetIntegerSize(binr);59 MODULUS =binr.ReadBytes(elems);60

61 elems =GetIntegerSize(binr);62 E =binr.ReadBytes(elems);63

64 elems =GetIntegerSize(binr);65 D =binr.ReadBytes(elems);66

67 elems =GetIntegerSize(binr);68 P =binr.ReadBytes(elems);69

70 elems =GetIntegerSize(binr);71 Q =binr.ReadBytes(elems);72

73 elems =GetIntegerSize(binr);74 DP =binr.ReadBytes(elems);75

76 elems =GetIntegerSize(binr);77 DQ =binr.ReadBytes(elems);78

79 elems =GetIntegerSize(binr);80 IQ =binr.ReadBytes(elems);81

82

83 //------- create RSACryptoServiceProvider instance and initialize with public key -----

84 CspParameters CspParameters = newCspParameters();85 CspParameters.Flags =CspProviderFlags.UseMachineKeyStore;86 RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters);87 RSAParameters RSAparams = newRSAParameters();88 RSAparams.Modulus =MODULUS;89 RSAparams.Exponent =E;90 RSAparams.D =D;91 RSAparams.P =P;92 RSAparams.Q =Q;93 RSAparams.DP =DP;94 RSAparams.DQ =DQ;95 RSAparams.InverseQ =IQ;96 RSA.ImportParameters(RSAparams);97 returnRSA;98 }99 catch(Exception ex)100 {101 return null;102 }103 finally

104 {105 binr.Close();106 }107 }108

109 private static intGetIntegerSize(BinaryReader binr)110 {111 byte bt = 0;112 byte lowbyte = 0x00;113 byte highbyte = 0x00;114 int count = 0;115 bt =binr.ReadByte();116 if (bt != 0x02) //expect integer

117 return 0;118 bt =binr.ReadByte();119

120 if (bt == 0x81)121 count = binr.ReadByte(); //data size in next byte

122 else

123 if (bt == 0x82)124 {125 highbyte = binr.ReadByte(); //data size in next 2 bytes

126 lowbyte =binr.ReadByte();127 byte[] modint = { lowbyte, highbyte, 0x00, 0x00};128 count = BitConverter.ToInt32(modint, 0);129 }130 else

131 {132 count = bt; //we already have the data size

133 }134

135 while (binr.ReadByte() == 0x00)136 { //remove high order zeros in data

137 count -= 1;138 }139 binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte

140 returncount;141 }142

143

144 ///

145 ///2进制转16进制146 ///

147 public staticString Hex_2To16(Byte[] bytes)148 {149 String hexString =String.Empty;150 Int32 iLength = 65535;151 if (bytes != null)152 {153 StringBuilder strB = newStringBuilder();154

155 if (bytes.Length

160 for (int i = 0; i < iLength; i++)161 {162 strB.Append(bytes[i].ToString("X2"));163 }164 hexString =strB.ToString();165 }166 returnhexString;167 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值