1.JAVA方法:
import org.apache.commons.codec.binary.Base64;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSAUtils {
public static final String CHARSET = "UTF-8";
public static final String RSA_ALGORITHM = "RSA"; // ALGORITHM ['ælgərɪð(ə)m] 算法的意思
public static Map<String, String> createKeys(int keySize) {
// 为RSA算法创建一个KeyPairGenerator对象
KeyPairGenerator kpg;
try {
kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
}
// 初始化KeyPairGenerator对象,密钥长度
kpg.initialize(keySize);
// 生成密匙对
KeyPair keyPair = kpg.generateKeyPair();
// 得到公钥
Key publicKey = keyPair.getPublic();
String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
// 得到私钥
Key privateKey = keyPair.getPrivate();
String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
// map装载公钥和私钥
Map<String, String> keyPairMap = new HashMap<String, String>();
keyPairMap.put("publicKey", publicKeyStr);
keyPairMap.put("privateKey", privateKeyStr);
// 返回map
return keyPairMap;
}
/**
* 得到公钥
* @param publicKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeySpecException {
// 通过X509编码的Key指令获得公钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
return key;
}
/**
* 得到私钥
* @param privateKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
// 通过PKCS#8编码的Key指令获得私钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
/**
* 公钥加密
* @param data
* @param publicKey
* @return
*/
public static String publicEncrypt(String data, RSAPublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
}
public static String publicEncrypt(String data, String publicKey) throws Exception {
try {
return publicEncrypt(data, getPublicKey(publicKey));
}catch (Exception e){
throw new Exception("加密字符串[" + data + "]时遇到异常");
}
}
/**
* 私钥解密
* @param data
* @param privateKey
* @return
*/
public static String privateDecrypt(String data, RSAPrivateKey privateKey) throws Exception{
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
}
public static String privateDecrypt(String data, String privateKey) throws Exception {
try {
return privateDecrypt(data, getPrivateKey(privateKey));
}catch (Exception e){
e.printStackTrace();
throw new Exception("解密字符串[" + data + "]时遇到异常");
}
}
/**
* 私钥加密
* @param data
* @param privateKey
* @return
*/
public static String privateEncrypt(String data, RSAPrivateKey privateKey) throws Exception {
Cipher cipher = null;
try {
cipher = Cipher.getInstance(RSA_ALGORITHM);
//每个Cipher初始化方法使用一个模式参数opmod,并用此模式初始化Cipher对象。此外还有其他参数,包括密钥key、包含密钥的证书certificate、算法参数params和随机源random。
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), privateKey.getModulus().bitLength()));
} catch (Exception e) {
throw new Exception("加密字符串[" + data + "]时遇到异常");
}
}
/**
* 公钥解密
* 公钥解密
* @param data
* @param publicKey
* @return
*/
public static String publicDecrypt(String data, RSAPublicKey publicKey) throws Exception {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET);
} catch (Exception e) {
throw new Exception("解密字符串[" + data + "]时遇到异常");
}
}
//rsa切割解码 , ENCRYPT_MODE,加密数据 ,DECRYPT_MODE,解密数据
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) throws Exception {
int maxBlock = 0; //最大块
if (opmode == Cipher.DECRYPT_MODE) {
maxBlock = keySize / 8;
} else {
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try {
while (datas.length > offSet) {
if (datas.length - offSet > maxBlock) {
//可以调用以下的doFinal()方法完成加密或解密数据:
buff = cipher.doFinal(datas, offSet, maxBlock);
} else {
buff = cipher.doFinal(datas, offSet, datas.length - offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
} catch (Exception e) {
throw new Exception("加解密阀值为[" + maxBlock + "]的数据时发生异常");
}
byte[] resultDatas = out.toByteArray();
IOUtils.closeQuietly(out);
return resultDatas;
}
public static void main(String[] args) throws Exception {
// 私钥
String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI4GE5mdRce9tQFK3fWchAyjiBIhXqKRA5E_pO4zcSSuAL0LlgZgue6NgP51H77crL2JAloG3TFbsuULwdqsI0jUnAjZmunS6UhSx21RC2XocwUWLNq6os5woHz_RAJxAHdwsKyKt87TO1YFfJV-Ym3VaAMaIkMW4BEpfan_QsN1AgMBAAECgYAaBbMBqndmqbPIkNcqcYsgZbZA3CxizP9CVc76diJ8_gTUnpLWiFKJCxRfi0ZNylE8SSZNKITOzmZw4T6bun6cScXtgKTzzTiijOVZJUp_1iAzu9hIba-jmJ_1s8KCuxve1J3PGMozDcOcFGma9yORrDReBDy5_44tFCj4_-VU4QJBAPFSXO2ass0yxEnjA4hrqZLjAYvcU-U5nv1CbxcRmtnhA3KPruflD7LqgicUlkTRB1WXqGiZ4I3k1Q9DUKTVrUMCQQCWqYmr0hIi9BcaocTNfgcF6dsIcCiPpz1Cg3DrQyapD4ziDyyRZjFlwmBnaNztiFgB0SjhDv0ipVkL8Wm1MiTnAkEAjOo4Y3KrKBGV90M9o-KiYah3FbFxt---vEqXzhO0pbe0KKhoTPdABIzVtXZbDRI2Qy_M4k_AhXrzQvde1vIDOwJAaFbzhC4Q52oaEhSUYif0nzDMwzRBsvMEZur2qcewn4aob-pIWE3oyetqrlMeJda19FQxNmQWBQdz-uRu69DVYwJAOy3rbwIXJTFWh1d6TNIqZHClO-w84dt7teYMuJ28dTty7VmGPB_g_rKetROePYbBLzuQe-xHqUKAGKw1oUHQ3A";
// 公钥
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCOBhOZnUXHvbUBSt31nIQMo4gSIV6ikQORP6TuM3EkrgC9C5YGYLnujYD-dR--3Ky9iQJaBt0xW7LlC8HarCNI1JwI2Zrp0ulIUsdtUQtl6HMFFizauqLOcKB8_0QCcQB3cLCsirfO0ztWBXyVfmJt1WgDGiJDFuARKX2p_0LDdQIDAQAB";
String data = "I am a good boy";
System.out.println("加密前字符串:" + data);
// 公钥加密 私钥解密
String dataEnc = publicEncrypt(data, publicKey);
System.out.println("加密后字符串: " + dataEnc);
String res = privateDecrypt(dataEnc, privateKey);
System.out.println("解密后字符串:" + res);
}
}
这里是JAVA生成秘钥的方法以及加密解密的方法
因为我要直接把JAVA生成的RSA加密字符串直接传给接口API接口,来实现使用公钥解密,所以同样的要使用到C#语言对应的RSA加密解密方法类(注:因为我这边只需要加密和解密,所以我没有在类里写生成密钥的方法,如若需要,可自行百度)
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
namespace ZHIHUI.WebSite.utils
{
public class RSACryption
{
/// <summary>
/// RSA加密 将公钥导入到RSA对象中,准备加密
/// </summary>
/// <param name="publicKey">公钥</param>
/// <param name="encryptstring">待加密的字符串</param>
public static string RsaEncrypt(string publicKey, string encryptstring)
{
using (var rsaProvider = new RSACryptoServiceProvider())
{
var inputBytes = Encoding.UTF8.GetBytes(encryptstring);//有含义的字符串转化为字节流
rsaProvider.FromXmlString(publicKey);//载入公钥
int bufferSize = (rsaProvider.KeySize / 8) - 11;//单块最大长度
var buffer = new byte[bufferSize];
using (MemoryStream inputStream = new MemoryStream(inputBytes), outputStream = new MemoryStream())
{
while (true)
{ //分段加密
int readSize = inputStream.Read(buffer, 0, bufferSize);
if (readSize <= 0)
{
break;
}
var temp = new byte[readSize];
Array.Copy(buffer, 0, temp, 0, readSize);
var encryptedBytes = rsaProvider.Encrypt(temp, false);
outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);
}
return Convert.ToBase64String(outputStream.ToArray());//转化为字节流方便传输
}
}
}
/// <summary>
/// RSA解密 载入私钥,解密数据
/// </summary>
/// <param name="privateKey">私钥</param>
/// <param name="decryptstring">待解密的字符串</param>
public static string RsaDecrypt(string privateKey, string decryptstring)
{
using (var rsaProvider = new RSACryptoServiceProvider())
{
rsaProvider.FromXmlString(privateKey); //载入私钥
//去除字符串中的多余字符,并替换特殊字符,以便能够正确地进行 Base64 解码
string dummyData = decryptstring.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+");
//特殊字符转换为标准的 Base64 字符,以便能够正确地进行解码操作
string standardBase64String = dummyData.Replace('-', '+').Replace('_', '/');
// 修正长度
while (standardBase64String.Length % 4 != 0)
{
standardBase64String += "=";
}
var encryptedBytes = Convert.FromBase64String(standardBase64String); //将传入的字符串转化为字节流
// var outputStream = new MemoryStream(encryptedBytes);
var bufferSize = rsaProvider.KeySize / 8;
var buffer = new byte[bufferSize];
using (MemoryStream inputStream = new MemoryStream(encryptedBytes), outputStream = new MemoryStream())
{
while (true)
{
int readSize = inputStream.Read(buffer, 0, bufferSize);
if (readSize <= 0)
{
break;
}
var temp = new byte[readSize];
Array.Copy(buffer, 0, temp, 0, readSize);
var decryptedBytes = rsaProvider.Decrypt(temp, false);
outputStream.Write(decryptedBytes, 0, decryptedBytes.Length);
}
return Encoding.UTF8.GetString(outputStream.ToArray()); //转化为字符串
}
}
}
/// <summary>
/// RSA私钥加密
/// </summary>
/// <param name="privateKey">私钥</param>
/// <param name="encryptstring">待加密的字符串</param>
public static string RsaPrivateEncrypt(string privateKey, string encryptstring)
{
var rsaProvider = new RSACryptoServiceProvider();
rsaProvider.FromXmlString(privateKey);//载入私钥
var inputBytes = Convert.FromBase64String(encryptstring);//有含义的字符串转化为字节流
int bufferSize = (rsaProvider.KeySize / 8) - 11;//单块最大长度
var buffer = new byte[bufferSize];
using (MemoryStream inputStream = new MemoryStream(inputBytes), outputStream = new MemoryStream())
{
while (true)
{
//分段加密
int readSize = inputStream.Read(buffer, 0, bufferSize);
if (readSize <= 0)
{
break;
}
var temp = new byte[readSize];
Array.Copy(buffer, 0, temp, 0, readSize);
var encryptedBytes = RsaPrivateEncrypt(privateKey, temp);
outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);
}
return Convert.ToBase64String(outputStream.ToArray());//转化为字节流方便传输
}
}
/// <summary>
/// RSA公钥解密
/// </summary>
/// <param name="publicKey">公钥</param>
/// <param name="decryptstring">待解密的字符串</param>
public static string RsaPublicDecrypt(string publicKey, string decryptstring)
{
var rsaProvider = new RSACryptoServiceProvider();
rsaProvider.FromXmlString(publicKey); //载入私钥
var encryptedBytes = Convert.FromBase64String(decryptstring); //将传入的字符串转化为字节流
var bufferSize = rsaProvider.KeySize / 8;
var buffer = new byte[bufferSize];
using (MemoryStream inputStream = new MemoryStream(encryptedBytes), outputStream = new MemoryStream())
{
while (true)
{
int readSize = inputStream.Read(buffer, 0, bufferSize);
if (readSize <= 0)
{
break;
}
var temp = new byte[readSize];
Array.Copy(buffer, 0, temp, 0, readSize);
var decryptedBytes = decryptByPublicKey(publicKey, temp);
outputStream.Write(decryptedBytes, 0, decryptedBytes.Length);
}
return Convert.ToBase64String(outputStream.ToArray());
}
}
/// <summary>
/// 私钥加密
/// 这个方法只能加密 私钥长度/8 -11 个字符,分段加密的代码要自己处理了。
/// </summary>
/// <param name="privateKey">密钥</param>
/// <param name="data">要加密的数据</param>
/// <returns></returns>
public static byte[] RsaPrivateEncrypt(string privateKey, byte[] data)
{
string xmlPrivateKey = privateKey;
//加载私钥
RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();
privateRsa.FromXmlString(xmlPrivateKey);
//转换密钥
AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);
//IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致
IBufferedCipher c = CipherUtilities.GetCipher("RSA");
c.Init(true, keyPair.Private); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
byte[] DataToEncrypt = data;
byte[] outBytes = c.DoFinal(DataToEncrypt);//加密
return outBytes;
}
/// <summary>
/// 用公钥解密
/// 这个方法只能加密 私钥长度/8 -11 个字符,分段加密的代码要自己处理了。
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <returns></returns>
public static byte[] decryptByPublicKey(string publicKey, byte[] data)
{
string xmlPublicKey = publicKey;
RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();
publicRsa.FromXmlString(xmlPublicKey);
AsymmetricKeyParameter keyPair = DotNetUtilities.GetRsaPublicKey(publicRsa);
//转换密钥
// AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(publicRsa);
//IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致
IBufferedCipher c = CipherUtilities.GetCipher("RSA");
c.Init(false, keyPair); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
byte[] DataToEncrypt = data;
byte[] outBytes = c.DoFinal(DataToEncrypt);//解密
return outBytes;
}
}
}
下面是我的接口调用方式:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Web.Http;
using ZHIHUI.WebSite.utils;
namespace ZHIHUI.WebAPI.Controllers
{
public class UserMessageController : ApiController
{
[HttpPost]
public string GetUserMessage(HttpRequestMessage request)
{
DateTime time = DateTime.Now;
try
{
var stream = request.Content.ReadAsStreamAsync().Result;
var reader = new StreamReader(stream);
string RSAString = reader.ReadToEnd();
string privteKey = "您的私钥";
//获取RSA加密后的字符串
//string RSAString = Convert.ToString(obj.RSAString);
//将获取到的私钥由java格式转换为net格式
string privtkey = RSAUtil.RSAPrivateKeyJavaToDotNet(privteKey);
//解密后的字符串
string Data = RSACryption.RsaDecrypt(privtkey, RSAString );
try
{
UserResult res = JsonConvert.DeserializeObject<UserResult>(Data);
}
catch (Exception)
{
throw;
}
return JsonConvert.SerializeObject(new { code = 200});
}
catch (Exception e)
{
return JsonConvert.SerializeObject(new { code = -1, msg = "Error", error = e.Message });
}
}
}
}
在解析秘钥时,需要将秘钥转换成C#所需要的格式
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
/// <summary>
/// C# Rsa加密(私钥加密、公钥解密、密钥格式转换、支持超大长度分段加密)
/// </summary>
public class RSAUtil
{
/// <summary>
/// 生成公钥与私钥方法
/// </summary>
/// <returns></returns>
public static string[] CreateKey(KeyType keyType, KeySize keySize)
{
try
{
string[] sKeys = new string[2];
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider((int)keySize);
switch (keyType)
{
case KeyType.XML:
{
//私钥
sKeys[0] = rsa.ToXmlString(true);
//公钥
sKeys[1] = rsa.ToXmlString(false);
}
break;
case KeyType.PKS8:
{
sKeys[0] = rsa.ToXmlString(true);
//公钥
sKeys[1] = rsa.ToXmlString(false);
//JAVA私钥
sKeys[0] = RSAPrivateKeyDotNet2Java(sKeys[0]);
//JAVA公钥
sKeys[1] = RSAPublicKeyDotNet2Java(sKeys[1]);
}
break;
default:
break;
}
return sKeys;
}
catch (Exception)
{
return null;
}
}
/// <summary>
/// 密钥类型
/// </summary>
public enum KeyType
{
/// <summary>
/// xml类型
/// </summary>
XML,
/// <summary>
/// pks8类型
/// </summary>
PKS8
}
/// <summary>
/// 密钥尺寸(一般都是1024位的)
/// </summary>
public enum KeySize
{
SMALL = 1024,
BIG = 2048
}
/// <summary>
/// RSA私钥格式转换,.net->java
/// </summary>
/// <param name="privateKey">.net生成的私钥</param>
/// <returns></returns>
public static string RSAPrivateKeyDotNet2Java(string privateKey)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(privateKey);
BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));
RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
return Convert.ToBase64String(serializedPrivateBytes);
}
/// <summary>
/// RSA公钥格式转换,.net->java
/// </summary>
/// <param name="publicKey">.net生成的公钥</param>
/// <returns></returns>
public static string RSAPublicKeyDotNet2Java(string publicKey)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(publicKey);
BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
RsaKeyParameters pub = new RsaKeyParameters(false, m, p);
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
return Convert.ToBase64String(serializedPublicBytes);
}
/// <summary>
/// RSA私钥格式转换,java->.net
/// </summary>
/// <param name="privateKey">java生成的RSA私钥</param>
/// <returns></returns>
public static string RSAPrivateKeyJavaToDotNet(string privateKey)
{
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
}
/// <summary>
/// RSA公钥格式转换,java->.net
/// </summary>
/// <param name="publicKey">java生成的公钥</param>
/// <returns></returns>
public static string RSAPublicKeyJavaToDotNet(string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
}
/// <summary>
/// 最大加密长度
/// </summary>
private const int MAX_ENCRYPT_BLOCK = 245;
/// <summary>
/// 最大解密长度
/// </summary>
private const int MAX_DECRYPT_BLOCK = 256;
/// <summary>
/// 用私钥给数据进行RSA加密
/// </summary>
/// <param name="xmlPrivateKey"></param>
/// <param name="strEncryptString"></param>
/// <returns></returns>
public static string PrivateKeyEncrypt(string xmlPrivateKey, string strEncryptString)
{
//加载私钥
RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();
privateRsa.FromXmlString(xmlPrivateKey);
//转换密钥
AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);
IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding"); //使用RSA/ECB/PKCS1Padding格式
c.Init(true, keyPair.Private);//第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
byte[] dataToEncrypt = Encoding.UTF8.GetBytes(strEncryptString);//获取字节
byte[] cache;
int time = 0;//次数
int inputLen = dataToEncrypt.Length;
int offSet = 0;
MemoryStream outStream = new MemoryStream();
while (inputLen - offSet > 0)
{
if (inputLen - offSet > MAX_ENCRYPT_BLOCK)
{
cache = c.DoFinal(dataToEncrypt, offSet, MAX_ENCRYPT_BLOCK);
}
else
{
cache = c.DoFinal(dataToEncrypt, offSet, inputLen - offSet);
}
//写入
outStream.Write(cache, 0, cache.Length);
time++;
offSet = time * MAX_ENCRYPT_BLOCK;
}
byte[] resData = outStream.ToArray();
string strBase64 = Convert.ToBase64String(resData);
outStream.Close();
return strBase64;
}
/// <summary>
/// 用公钥给数据进行RSA解密
/// </summary>
/// <param name="xmlPublicKey"> 公钥(XML格式字符串) </param>
/// <param name="strDecryptString"> 要解密数据 </param>
/// <returns> 解密后的数据 </returns>
public static string PublicKeyDecrypt(string xmlPublicKey, string strDecryptString)
{
//加载公钥
RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();
publicRsa.FromXmlString(xmlPublicKey);
RSAParameters rp = publicRsa.ExportParameters(false);
//转换密钥
AsymmetricKeyParameter pbk = DotNetUtilities.GetRsaPublicKey(rp);
IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
//第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
c.Init(false, pbk);
byte[] DataToDecrypt = Convert.FromBase64String(strDecryptString);
byte[] cache;
int time = 0;//次数
int inputLen = DataToDecrypt.Length;
int offSet = 0;
MemoryStream outStream = new MemoryStream();
while (inputLen - offSet > 0)
{
if (inputLen - offSet > MAX_DECRYPT_BLOCK)
{
cache = c.DoFinal(DataToDecrypt, offSet, MAX_DECRYPT_BLOCK);
}
else
{
cache = c.DoFinal(DataToDecrypt, offSet, inputLen - offSet);
}
//写入
outStream.Write(cache, 0, cache.Length);
time++;
offSet = time * MAX_DECRYPT_BLOCK;
}
byte[] resData = outStream.ToArray();
string strDec = Encoding.UTF8.GetString(resData);
return strDec;
}
/// <summary>
/// 签名
/// </summary>
/// <param name="str">需签名的数据</param>
/// <returns>签名后的值</returns>
public static string Sign(string str, string privateKey, SignAlgType signAlgType)
{
//根据需要加签时的哈希算法转化成对应的hash字符节
byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
byte[] rgbHash = null;
switch (signAlgType)
{
case SignAlgType.SHA256:
{
SHA256CryptoServiceProvider csp = new SHA256CryptoServiceProvider();
rgbHash = csp.ComputeHash(bt);
}
break;
case SignAlgType.MD5:
{
MD5CryptoServiceProvider csp = new MD5CryptoServiceProvider();
rgbHash = csp.ComputeHash(bt);
}
break;
case SignAlgType.SHA1:
{
SHA1 csp = new SHA1CryptoServiceProvider();
rgbHash = csp.ComputeHash(bt);
}
break;
default:
break;
}
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
key.FromXmlString(privateKey);
RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
formatter.SetHashAlgorithm(signAlgType.ToString());//此处是你需要加签的hash算法,需要和上边你计算的hash值的算法一致,不然会报错。
byte[] inArray = formatter.CreateSignature(rgbHash);
return Convert.ToBase64String(inArray);
}
/// <summary>
/// 签名验证
/// </summary>
/// <param name="str">待验证的字符串</param>
/// <param name="sign">加签之后的字符串</param>
/// <returns>签名是否符合</returns>
public static bool Verify(string str, string sign, string publicKey, SignAlgType signAlgType)
{
byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
byte[] rgbHash = null;
switch (signAlgType)
{
case SignAlgType.SHA256:
{
SHA256CryptoServiceProvider csp = new SHA256CryptoServiceProvider();
rgbHash = csp.ComputeHash(bt);
}
break;
case SignAlgType.MD5:
{
MD5CryptoServiceProvider csp = new MD5CryptoServiceProvider();
rgbHash = csp.ComputeHash(bt);
}
break;
case SignAlgType.SHA1:
{
SHA1 csp = new SHA1CryptoServiceProvider();
rgbHash = csp.ComputeHash(bt);
}
break;
default:
break;
}
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
key.FromXmlString(publicKey);
RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
deformatter.SetHashAlgorithm(signAlgType.ToString());
byte[] rgbSignature = Convert.FromBase64String(sign);
if (deformatter.VerifySignature(rgbHash, rgbSignature))
return true;
return false;
}
/// <summary>
/// 签名算法类型
/// </summary>
public enum SignAlgType
{
/// <summary>
/// sha256
/// </summary>
SHA256,
/// <summary>
/// md5
/// </summary>
MD5,
/// <summary>
/// sha1
/// </summary>
SHA1
}
}
因为我在转换的时候遇到过问题,所以把问题整理一下,以供大家参考:
1.返回的字符串非法
我们可以清晰的知道该字符串不能够解析的原因是因为里面含有非法字符,所以我们要是解决这个问题,可以把那些非法字符给替换成base-64编码所需要的字符串
红色标记的代码就是用来修改字符串为正确的base-64编码,如果传的字符过长,需要修正他 的长度,以上便是所需代码,代码如有侵权,请联系我