RSA算法 Android JAVA C#互通
RSA算法属非对称加密算法,在实际使用中,往往客户端使用公钥进行加密传递敏感数据,服务端server使用私钥进行解密,这样防止中间人从网络获取敏感数据的明文。
Android端主要代码如下:
package com.example.rsatest; import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Date; import javax.crypto.Cipher; public class RsaHelper
{
/**
* 生成RSA密钥对(默认密钥长度为1024)
*
* @return
*/
public static KeyPair generateRSAKeyPair()
{
return generateRSAKeyPair(1024);
} /**
* 生成RSA密钥对
*
* @param keyLength 密钥长度,范围:512~2048
* @return
*/
public static KeyPair generateRSAKeyPair(int keyLength)
{
try
{
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA/ECB/PKCS1Padding");
kpg.initialize(keyLength);
return kpg.genKeyPair();
}
catch (NoSuchAlgorithmException e)
{
return null;
}
} /*
* java端公钥转换成C#公钥
*/
public static String encodePublicKeyToXml(PublicKey key)
{
if (!RSAPublicKey.class.isInstance(key))
{
return null;
}
RSAPublicKey pubKey = (RSAPublicKey) key;
StringBuilder sb = new StringBuilder(); sb.append("<RSAKeyValue>");
sb.append("<Modulus>")
.append(Base64Helper.encode(pubKey.getModulus().toByteArray()))
.append("</Modulus>");
sb.append("<Exponent>")
.append(Base64Helper.encode(pubKey.getPublicExponent().toByteArray()))
.append("</Exponent>");
sb.append("</RSAKeyValue>");
return sb.toString();
} /*
* C#端公钥转换成java公钥
*/
public static PublicKey decodePublicKeyFromXml(String xml)
{
xml = xml.replaceAll("\r", "").replaceAll("\n", "");
BigInteger modulus =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
"<Modulus>", "</Modulus>")));
BigInteger publicExponent =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
"<Exponent>", "</Exponent>"))); RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, publicExponent); KeyFactory keyf;
try
{
keyf = KeyFactory.getInstance("RSA");
return keyf.generatePublic(rsaPubKey);
}
catch (Exception e)
{
return null;
}
} /*
* C#端私钥转换成java私钥
*/
public static PrivateKey decodePrivateKeyFromXml(String xml)
{
xml = xml.replaceAll("\r", "").replaceAll("\n", "");
BigInteger modulus =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
"<Modulus>", "</Modulus>")));
BigInteger publicExponent =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
"<Exponent>", "</Exponent>")));
BigInteger privateExponent =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml, "<D>",
"</D>")));
BigInteger primeP =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml, "<P>",
"</P>")));
BigInteger primeQ =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml, "<Q>",
"</Q>")));
BigInteger primeExponentP =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
"<DP>", "</DP>")));
BigInteger primeExponentQ =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
"<DQ>", "</DQ>")));
BigInteger crtCoefficient =
new BigInteger(1, Base64Helper.decode(StringUtils.getMiddleString(xml,
"<InverseQ>", "</InverseQ>"))); RSAPrivateCrtKeySpec rsaPriKey =
new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP,
primeQ, primeExponentP, primeExponentQ, crtCoefficient); KeyFactory keyf;
try
{
keyf = KeyFactory.getInstance("RSA");
return keyf.generatePrivate(rsaPriKey);
}
catch (Exception e)
{
return null;
}
} /*
* java端私钥转换成C#私钥
*/
public static String encodePrivateKeyToXml(PrivateKey key)
{
if (!RSAPrivateCrtKey.class.isInstance(key))
{
return null;
}
RSAPrivateCrtKey priKey = (RSAPrivateCrtKey) key;
StringBuilder sb = new StringBuilder(); sb.append("<RSAKeyValue>");
sb.append("<Modulus>")
.append(Base64Helper.encode(priKey.getModulus().toByteArray()))
.append("</Modulus>");
sb.append("<Exponent>")
.append(Base64Helper.encode(priKey.getPublicExponent().toByteArray()))
.append("</Exponent>");
sb.append("<P>").append(Base64Helper.encode(priKey.getPrimeP().toByteArray()))
.append("</P>");
sb.append("<Q>").append(Base64Helper.encode(priKey.getPrimeQ().toByteArray()))
.append("</Q>");
sb.append("<DP>")
.append(Base64Helper.encode(priKey.getPrimeExponentP().toByteArray()))
.append("</DP>");
sb.append("<DQ>")
.append(Base64Helper.encode(priKey.getPrimeExponentQ().toByteArray()))
.append("</DQ>");
sb.append("<InverseQ>")
.append(Base64Helper.encode(priKey.getCrtCoefficient().toByteArray()))
.append("</InverseQ>");
sb.append("<D>")
.append(Base64Helper.encode(priKey.getPrivateExponent().toByteArray()))
.append("</D>");
sb.append("</RSAKeyValue>");
return sb.toString();
} // 用公钥加密
public static byte[] encryptData(byte[] data, PublicKey pubKey)
{
try
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return cipher.doFinal(data);
}
catch (Exception e)
{
return null;
}
} // 用私钥解密
public static byte[] decryptData(byte[] encryptedData, PrivateKey priKey)
{
try
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, priKey);
return cipher.doFinal(encryptedData);
}
catch (Exception e)
{
return null;
}
} /**
* 根据指定公钥进行明文加密
*
* @param plainText 要加密的明文数据
* @param pubKey 公钥
* @return
*/
public static String encryptDataFromStr(String plainText, PublicKey pubKey)
{ try
{
byte[] dataByteArray = plainText.getBytes("UTF-8");
byte[] encryptedDataByteArray = RsaHelper.encryptData(dataByteArray, pubKey);
return Base64Helper.encode(encryptedDataByteArray);
}
catch (UnsupportedEncodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
} /**
* 根据指定私钥对数据进行签名(默认签名算法为"SHA1withRSA")
*
* @param data 要签名的数据
* @param priKey 私钥
* @return
*/
public static byte[] signData(byte[] data, PrivateKey priKey)
{
return signData(data, priKey, "SHA1withRSA");
} /**
* 根据指定私钥和算法对数据进行签名
*
* @param data 要签名的数据
* @param priKey 私钥
* @param algorithm 签名算法
* @return
*/
public static byte[] signData(byte[] data, PrivateKey priKey, String algorithm)
{
try
{
Signature signature = Signature.getInstance(algorithm);
signature.initSign(priKey);
signature.update(data);
return signature.sign();
}
catch (Exception ex)
{
return null;
}
} /**
* 用指定的公钥进行签名验证(默认签名算法为"SHA1withRSA")
*
* @param data 数据
* @param sign 签名结果
* @param pubKey 公钥
* @return
*/
public static boolean verifySign(byte[] data, byte[] sign, PublicKey pubKey)
{
return verifySign(data, sign, pubKey, "SHA1withRSA");
} /**
* @param data 数据
* @param sign 签名结果
* @param pubKey 公钥
* @param algorithm 签名算法
* @return
*/
public static boolean verifySign(byte[] data, byte[] sign, PublicKey pubKey,
String algorithm)
{
try
{
Signature signature = Signature.getInstance(algorithm);
signature.initVerify(pubKey);
signature.update(data);
return signature.verify(sign);
}
catch (Exception ex)
{
return false;
}
} public static void main(String[] args)
{
KeyPair kp = RsaHelper.generateRSAKeyPair();
PublicKey pubKey = kp.getPublic();
PrivateKey priKey = kp.getPrivate(); String pubKeyXml = RsaHelper.encodePublicKeyToXml(pubKey);
String priKeyXml = RsaHelper.encodePrivateKeyToXml(priKey);
System.out.println("====公钥====");
System.out.println(pubKeyXml);
System.out.println("====私钥====");
System.out.println(priKeyXml); PublicKey pubKey2 = RsaHelper.decodePublicKeyFromXml(pubKeyXml);
PrivateKey priKey2 = RsaHelper.decodePrivateKeyFromXml(priKeyXml); System.out.println("====公钥对比====");
System.out.println(pubKey.toString());
System.out.println("------");
System.out.println(pubKey2.toString()); System.out.println("====私钥对比====");
System.out.println(priKey.toString());
System.out.println("------");
System.out.println(priKey2.toString()); try
{
String pubKeyXml3 =
"<RSAKeyValue><Modulus>rHESyuI3ny4MLsqDBalW9ySaodCL0e6Bsrl01Q5G1qm2wjUoGULazZSNqZY+JQNjU92tW3Snk5RPIkv+wDj+uOT9LTUjQImltHnzqMvbt06GipVXDOyBLTa7G/zRIe/CrjyJ+XEYX2xIhpe5ayowl3HHUpZ71jRNioyxaVVZ8S0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
String priKeyXml3 =
"<RSAKeyValue><Modulus>rHESyuI3ny4MLsqDBalW9ySaodCL0e6Bsrl01Q5G1qm2wjUoGULazZSNqZY+JQNjU92tW3Snk5RPIkv+wDj+uOT9LTUjQImltHnzqMvbt06GipVXDOyBLTa7G/zRIe/CrjyJ+XEYX2xIhpe5ayowl3HHUpZ71jRNioyxaVVZ8S0=</Modulus><Exponent>AQAB</Exponent><P>5a7uM+IeY8QMVQl0q88ZTqWbB555l7+366cUIClTN8z2ZXzTnWFCNoQzUrG14FouJFYumFZD12Ni5MkJK6gqSw==</P><Q>wDMhwwO4kz82uSG+FlCBr06fYk2COTg0TofmSp/5OrVqgkBIe7FgpTpVGzGLk0mvOLcy6UZftq//W0Saow6nZw==</Q><DP>FbjDgliiMyE5YVlxlUYSyKNU1BWivj09caXte1UtL5vMubBiewHVtz4tdGamIr+kmX8lDPcrl1Uo5yY0HdLbnQ==</DP><DQ>kIjjJsgxkWnEOUyKqjU4kSDK8x3ehDEkBLpmEFBlGCU9R14YJAyr5RUM0zpbABQ1VK1P9+UYLUYE/hmFQIHQmQ==</DQ><InverseQ>pxQDThwSnUZ4EaNaCPl1ovYypdQUZaZ/Sld1+0n8FEjkmRcGP1R9VMuj1ViPZg3rvm2GeP8Xv1SJqJUVueWiGA==</InverseQ><D>DxBNoPWEAF7IZ6n/KhZx52MGMw6BuFQKdm9m+lml7Iik03BLUXGapYzNlzvtr9QM8D2UMEIPhX/WLdvPpEEWVzGnD7XpLXjGwfu1ZkJRcXPEZEZ2subh5ZBqOWCFWKv5WwgGYWuYDLHfrBlBgSFWR8cZuyqkmMsWl4CiadXqGA0=</D></RSAKeyValue>"; System.out.println((new Date()).toLocaleString() + ": 加载公钥中。。。");
PublicKey pubKey3 = RsaHelper.decodePublicKeyFromXml(pubKeyXml3);
System.out.println((new Date()).toLocaleString() + ": 加载私钥中。。。");
PrivateKey priKey3 = RsaHelper.decodePrivateKeyFromXml(priKeyXml3); String dataStr = "Java与.NET和平共处万岁!";
byte[] dataByteArray = dataStr.getBytes("utf-8");
System.out.println("data的Base64表示:" + Base64Helper.encode(dataByteArray)); System.out.println((new Date()).toLocaleString() + ": 加密中。。。"); // 加密
byte[] encryptedDataByteArray = RsaHelper.encryptData(dataByteArray, pubKey3); System.out.println("encryptedData的Base64表示:"
+ Base64Helper.encode(encryptedDataByteArray));
System.out.println((new Date()).toLocaleString() + ": 解密中。。。"); // 解密
// byte[]
byte[] decryptedDataByteArray =
RsaHelper.decryptData(encryptedDataByteArray, priKey3);
System.out.println(new String(decryptedDataByteArray, "utf-8"));// 签名
System.out.println((new Date()).toLocaleString() + ": 签名中。。。");
byte[] signDataByteArray = RsaHelper.signData(dataByteArray, priKey3);
System.out.println("signData的Base64表示:"
+ Base64Helper.encode(signDataByteArray)); // 验签
System.out.println((new Date()).toLocaleString() + ": 验签中。。。");
boolean isMatch =
RsaHelper.verifySign(dataByteArray, signDataByteArray, pubKey3);
System.out.println("验签结果:" + isMatch); }
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
RsaHelper
Android客户端调用示例:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); btnencode = (Button) findViewById(R.id.btnencode);
btndecode = (Button) findViewById(R.id.btndecode);
txtinit = (EditText) findViewById(R.id.txtinit);
txtencoded = (EditText) findViewById(R.id.txtencoded);
txtencoded2 = (EditText) findViewById(R.id.txtencoded2);
lbldecoded = (TextView) findViewById(R.id.lbldecoded); btnencode.setOnClickListener(new OnClickListener()
{ @Override
public void onClick(View v)
{
// TODO Auto-generated method stub try
{
String strinit = txtinit.getText().toString().trim();
String rs = RsaHelper.encryptDataFromStr(strinit, publicKey);
txtencoded.setText(rs);
Log.e("decoded", rs);//将rs值拿到c#服务器可解密成功
}
catch (Exception e)
{
e.printStackTrace();
} }
}); btndecode.setOnClickListener(new OnClickListener()
{ @Override
public void onClick(View v)
{ try
{
String strtxtencoded = txtencoded2.getText().toString().trim(); //C#端加密的内容 也可解密
//strtxtencoded = "E7lS+MJCDImpS664YmwbFA+OqYlrLzPOw4/Lkg5aUnjZ/ztQkuh+6LtLGLU5T4aLpErVgI1+1tj74fnz1vv4XApK797uvxAiVIY2izZfwIF4M993Bx7Yy7JfciobXowp+eKsxhp4yrLuOZbM1kdNyhfvvOlMZNiLaXLpKyZat6A="; String rs = new String(RsaHelper.decryptData(
Base64Helper.decode(strtxtencoded), privateKey), "UTF-8");
lbldecoded.setText(rs);
Log.e("encoded", rs);
}
catch (Exception e)
{
e.printStackTrace();
} }
}); }
JAVA 客户端程序 加密示例:
public class RSAClient { private static int MAXENCRYPTSIZE = 117;
private static int MAXDECRYPTSIZE = 128; public static void main(String[] args) {
/*
*
* 以下xml格式由c#服务端生成的公钥
<RSAKeyValue>
<Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
*/
String modulus = "w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=";
String exponent ="AQAB"; PublicKey p =getPublicKey(modulus,exponent); //使用上述公钥 针对明文123abc进行加密
//step1.将明文转为BASE64格式
try {
String password = encodeBase64("123abc".getBytes());
byte[] by = decodeBase64(password);
String mask = encrypt(by,p);
System.out.println("请将以下密文复制到c#端进行解密");
System.out.println(mask);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
public static String encodeBase64(byte[] input) throws Exception {
Class clazz = Class
.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method mainMethod = clazz.getMethod("encode", byte[].class);
mainMethod.setAccessible(true);
Object retObj = mainMethod.invoke(null, new Object[] { input });
return (String) retObj;
}
public static byte[] decodeBase64(String input) throws Exception{
Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method mainMethod= clazz.getMethod("decode", String.class);
mainMethod.setAccessible(true);
Object retObj=mainMethod.invoke(null, input);
return (byte[])retObj;
} /**
* 返回RSA公钥
* @param modules
* @param exponent
* @return
*/
public static PublicKey getPublicKey(String modulus, String exponent){
try {
byte[] m = decodeBase64(modulus);
byte[] e = decodeBase64(exponent);
BigInteger b1 = new BigInteger(1,m);
BigInteger b2 = new BigInteger(1,e);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} public static String encrypt2(byte[] source, PublicKey publicKey) throws Exception { } public static String encrypt(byte[] source, PublicKey publicKey) throws Exception {
String encryptData ="";
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int length = source.length;
int offset = 0;
byte[] cache;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
int i = 0;
while(length - offset > 0){
if(length - offset > MAXENCRYPTSIZE){
cache = cipher.doFinal(source, offset, MAXENCRYPTSIZE);
}else{
cache = cipher.doFinal(source, offset, length - offset);
}
outStream.write(cache, 0, cache.length);
i++;
offset = i * MAXENCRYPTSIZE;
}
return encodeBase64(outStream.toByteArray());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return encryptData;
}
}
JAVA Client
服务器 端 C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks; namespace RSA_Android_Demo
{
/// <summary>
/// RSA 非对称加解密算法
/// </summary>
public class RSAHelper
{
private int MAXENCRYPTSIZE = ;
private int MAXDECRYPTSIZE = ; public string priKeyXml
{
get;
private set;
} public string pubKeyXml
{
get;
private set;
} private RSAHelper(string privateKey, string publicKey)
{
this.priKeyXml = privateKey;
this.pubKeyXml = publicKey;
} public static RSAHelper Load(string privateKey = "", string publicKey = "")
{
if (string.IsNullOrEmpty(privateKey) && string.IsNullOrEmpty(publicKey))
{
//无key时生成新密钥
return Instance;
}
return new RSAHelper(privateKey, publicKey);
} /// <summary>
/// 随机生成公私钥并返回对象
/// </summary>
public static RSAHelper Instance
{
get
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
var publicKeyXml = provider.ToXmlString(false);
//publickey:<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
var privateKeyXml = provider.ToXmlString(true);
//privatekey:<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent><P>6tzaLZmY+hLLAifunWwcdUSfqTUvKOO5bJ8M1Zt34en40tfBaH9zml9gP8cmXaWyfpiZgHlPS9xlkLngudAiJw==</P><Q>1Xw2E1ufXsCM2JZahB6PH9pCgfD4XPjrqxF9xOWVvfbPmVBZByBIHYRs8ifbjIPvSKuaCfVFVStoIcOYrT9I+w==</Q><DP>mS4iPsuHMtM/BND2mEYC6ZkwaTP+5jRgo6+4tzkHH5lyaFHAG1/FDlJWfEJvi3SezmLI+zojtd6xf4s8PvS40Q==</DP><DQ>I91kMEhaM87hWpmXx05i+RTvy2iyMNxYqzqbCHMRfwJxye3npvzTYLIYo23ywl5/2pOJo1ajOTW7nsB/a8uP9Q==</DQ><InverseQ>EtYQvvBViXf7A5bgh+H4xLlBezD0yziBigoP/xcg1mcuI9Kb9rtPq64hQsajDYeNmm0Ibkxz9ihHr8+uWtdi5w==</InverseQ><D>HSivw2RZKvDlv1lSb/gumEqufALcbF7W3SMS3qxAVGvC3z27Ks/jWTCVwWOg3u+LV99KZC+dk1MWbxq/dJhMmBSiHOT6Sg7wvNMmX58zHl7Bhs702henzbr7CkiWrUcy3pVigr4olT9FlkjQkeEu9VfVW4TRGUDUkixTeh9MMC0=</D></RSAKeyValue> return new RSAHelper(privateKeyXml, publicKeyXml);
}
} /// <summary>
/// RSA公钥加密
/// </summary>
/// <param name="content"></param>
/// <param name="publicKeyXml">公钥xml串</param>
/// <returns></returns>
public string Encrypt(string content)
{
//string publickey = @"<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(pubKeyXml);
cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false); return Convert.ToBase64String(cipherbytes);
//return cipherbytes;
}
/// <summary>
/// RSA私钥解密
/// </summary>
/// <param name="encryptData">经过Base64编码的密文</param>
/// <param name="privateKeyXml">私钥xml串</param>
/// <returns>RSA解密后的数据</returns>
public string Decrypt(string encryptData)
{
string decryptData = "";
try
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.FromXmlString(priKeyXml);
byte[] bEncrypt = Convert.FromBase64String(encryptData);
int length = bEncrypt.Length;
int offset = ;
string cache;
int i = ;
while (length - offset > )
{
if (length - offset > MAXDECRYPTSIZE)
{
cache = Encoding.UTF8.GetString(provider.Decrypt(GetSplit(bEncrypt, offset, MAXDECRYPTSIZE), false));
}
else
{
cache = Encoding.UTF8.GetString(provider.Decrypt(GetSplit(bEncrypt, offset, length - offset), false));
}
decryptData += cache;
i++;
offset = i * MAXDECRYPTSIZE;
}
}
catch (Exception e)
{
throw e;
}
return decryptData;
} /// <summary>
/// 截取字节数组部分字节
/// </summary>
/// <param name="input"></param>
/// <param name="offset">起始偏移位</param>
/// <param name="length">截取长度</param>
/// <returns></returns>
private byte[] GetSplit(byte[] input, int offset, int length)
{
byte[] output = new byte[length];
for (int i = offset; i < offset + length; i++)
{
output[i - offset] = input[i];
}
return output;
} } }
RSAHelper
C#调用示例
public void TestDecry()
{
//java端的密文
//以下为android端加密后的密文
string pwd =
"VpEiGrV8BND+30z/5n03eS7UW/0ZF7NgVnCKPp/5IrpGRI/aoDb0iNehTez8Gcnl1C/g0q71UjLVMjywysbdoTBCaLBq/x85Fw31NNvzc5XOW4St01Q3+78JKkX1CCmSbOPpb2lvMb0D8iGiq3gLt3UZZpLLkbyBZDaXP2oHaIc=";
//Convert.ToBase64String(bytes); //服务端私钥
string privateKey = "<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent><P>6tzaLZmY+hLLAifunWwcdUSfqTUvKOO5bJ8M1Zt34en40tfBaH9zml9gP8cmXaWyfpiZgHlPS9xlkLngudAiJw==</P><Q>1Xw2E1ufXsCM2JZahB6PH9pCgfD4XPjrqxF9xOWVvfbPmVBZByBIHYRs8ifbjIPvSKuaCfVFVStoIcOYrT9I+w==</Q><DP>mS4iPsuHMtM/BND2mEYC6ZkwaTP+5jRgo6+4tzkHH5lyaFHAG1/FDlJWfEJvi3SezmLI+zojtd6xf4s8PvS40Q==</DP><DQ>I91kMEhaM87hWpmXx05i+RTvy2iyMNxYqzqbCHMRfwJxye3npvzTYLIYo23ywl5/2pOJo1ajOTW7nsB/a8uP9Q==</DQ><InverseQ>EtYQvvBViXf7A5bgh+H4xLlBezD0yziBigoP/xcg1mcuI9Kb9rtPq64hQsajDYeNmm0Ibkxz9ihHr8+uWtdi5w==</InverseQ><D>HSivw2RZKvDlv1lSb/gumEqufALcbF7W3SMS3qxAVGvC3z27Ks/jWTCVwWOg3u+LV99KZC+dk1MWbxq/dJhMmBSiHOT6Sg7wvNMmX58zHl7Bhs702henzbr7CkiWrUcy3pVigr4olT9FlkjQkeEu9VfVW4TRGUDUkixTeh9MMC0=</D></RSAKeyValue>"; //解密
string userpwd = RSAHelper.Load(privateKey: privateKey).Decrypt(pwd); //C# 端用公钥加密
string publickey = @"<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"; var abc = RSAHelper.Load(publicKey: publickey).Encrypt("abc123中文");//查将此生成的值拿到android工程中解密,至此达到RSA 的 C#—Android双方互通 //C#端也可 解密
string userpwd2 = RSAHelper.Load(privateKey: privateKey).Decrypt(abc); }
可运行的示例代码下载:
RSA算法 Android JAVA C#互通的更多相关文章
- 一个基于RSA算法的Java数字签名例子
原文地址:一个基于RSA算法的Java数字签名例子 一.前言: 网络数据安全包括数据的本身的安全性.数据的完整性(防止篡改).数据来源的不可否认性等要素.对数据采用加密算法加密可以保证数据本身的安全性 ...
- RSA算法原理与加密解密 求私钥等价求求模反元素 等价于分解出2个质数 (r*X+1)%[(p-1)(q-1)]=0
Rsapaper.pdf http://people.csail.mit.edu/rivest/Rsapaper.pdf [概述Abstract 1.将字符串按照双方约定的规则转化为小于n的正整数m, ...
- IOS, Android, Java Web Rest : RSA 加密和解密问题
IOS, Android, Java Web Rest : RSA 加密和解密问题 一对公钥私钥可以使用 OpenSSL创建, 通常 1024位长度够了. 注意: 1. 公钥私钥是BASE64编码的 ...
- AES算法,DES算法,RSA算法JAVA实现
1 AES算法 1.1 算法描述 1.1.1 设计思想 Rijndael密码的设计力求满足以下3条标准: ① 抵抗所有已知的攻击. ② 在多个平台上速度快,编码紧凑. ③ 设计 ...
- Java中使用RSA算法加密
Java中使用RSA算法加密 概述 RSA加密算法是一种非对称加密算法 RSA加密的方式 使用公钥加密的数据,利用私钥进行解密 使用私钥加密的数据,利用公钥进行解密 RSA是一对密钥.分别是公钥和私钥 ...
- RSA算法java实现(BigInteger类的各种应用)
一.RSA算法 1.密钥生成 随机生成两个大素数p.q 计算n=p*q 计算n的欧拉函数f=(p-1)*(q-1) 选取1<e<f,使e与f互素 计算d,ed=1modf 公钥为(e,n) ...
- RSA加密的java实现2(交互IOS)
这里的base64的依赖不一样,一个是apache,一个是sun的 ,由于base64的依赖不同,导致在IOS中解析不了! package com.handsight.platform.cipher ...
- RSA加密算法的java实现
package rsa; import java.security.*;import java.security.interfaces.*;import javax.crypto.*; public ...
- .NET/android/java/iOS AES通用加密解密(修正安卓)
移动端越来越火了,我们在开发过程中,总会碰到要和移动端打交道的场景,比如.NET和android或者iOS的打交道.为了让数据交互更安全,我们需要对数据进行加密传输.今天研究了一下,把几种语言的加密都 ...
随机推荐
- JavaScript-创建新数组
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- ClickOnce的部署(.appref-ms)在软件限制策略中的解决方案
为了防止百度.360以及一些小厂商在妈妈的电脑里乱安装各种程序,在域中开启了软件限制策略. 今天在用Github的Windows客户端时发现由于软件限制策略无法运行. Github在Windows中采 ...
- Codeforces #259 Div.2
A. Little Pony and Crystal Mine 模拟题. 用矩阵直接构造或者直接根据关系输出 B. Little Pony and Sort by Shift 模拟题. 通过提供的操作 ...
- Eclipse格式化代码快捷键失效问题
一般情况下,Eclipse快捷键失效是因为与其它软件快捷键冲突,Eclipse格式化代码快捷键正好与搜狗输入法的“简繁切换”的快捷键冲突,将搜狗输入法的快捷键修改一下就行了.
- 在cocos2d里面如何使用Texture Packer和像素格式来优化spritesheet
免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...
- 手机端使用rem适配
最近一直在做手机端的东西,各种型号的手机适配很是无解.经过同事及百度找到了这么一个方法 html font-size默认100px 将rem进行换算1px==0.01rem; 页面在各个手机适配个别会 ...
- 大话JS面向对象之扩展篇 面向对象与面向过程之间的博弈论(OO Vs 过程)------(一个简单的实例引发的沉思)
一,总体概要 1,笔者浅谈 我是从学习Java编程开始接触OOP(面向对象编程),刚开始使用Java编写程序的时候感觉很别扭(面向对象式编程因为引入了类.对象.实例等概念,非常贴合人类对于世间万物的认 ...
- ajax请求的异步嵌套问题分析
(本文章以as3代码为例) 问题的产生 在前端开发时,经常会使用到Ajax(Asynchronous Javascript And XML)请求向服务器查询信息(get)或交换数据(post),aja ...
- AlwaysOn--查看可用性组的首先备份节点
在Alwayson中,可以通过设置来将备份放到指定的节点上完成,微软提供了函数用来判断当前指定节点进行备份: ) SET @database_name= 'DB5' SELECT CASE [mast ...
- 不要过早退出循环 while(1){no break}
我们在尝试新的事物的时候,总是会遇到各种各样的困难,不同的人会在碰壁不同的次数之后退出.用程序员喜欢的话来说就是,我们都在for循环,区别在于你是什么情况下break的.有的人退出阈值高,这是能坚持的 ...