using System;
using System.Text;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Encodings;
using System.IO;
namespace v4_RSAHelper
{
public class BCSignUtil
{
/// <summary>
/// 签名
/// </summary>
/// <param name="orgData">原数据字符串</param>
/// <param name="privateKeyPKCS8">必须是PKCS8的</param>
/// <param name="algorithm">算法</param>
/// <returns></returns>
public static string SignData(string orgData, string privateKeyPKCS8, string algorithm)
{
if (string.IsNullOrEmpty(orgData))
throw new Exception("字符串不能为空!");
if (string.IsNullOrEmpty(privateKeyPKCS8))
throw new Exception("privateKeyPKCS8不能为空!");
if (string.IsNullOrEmpty(privateKeyPKCS8))
throw new Exception("algorithm 不能为空!");
AsymmetricKeyParameter priKey = GetPrivateKeyParameter(privateKeyPKCS8);
byte[] byteData = Encoding.UTF8.GetBytes(orgData);
ISigner normalSig = SignerUtilities.GetSigner(algorithm);
normalSig.Init(true, priKey);
normalSig.BlockUpdate(byteData, 0, byteData.Length);//注意:是byte数组和数组长度,别写成string的长度了
byte[] normalResult = normalSig.GenerateSignature(); //签名结果
string sign = Convert.ToBase64String(normalResult);
return sign;
}
private static AsymmetricKeyParameter GetPrivateKeyParameter(string privateKeyPem)
{
//获取私钥纯字符串
privateKeyPem = privateKeyPem.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
privateKeyPem = privateKeyPem.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
byte[] privateInfoByte = Convert.FromBase64String(privateKeyPem);
AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
return priKey;
}
/// <summary>
/// 验证签名
/// </summary>
/// <param name="orgData">原数据字符串</param>
/// <param name="publicKeyPem">公钥</param>
/// <param name="responseSign">对方的签名串</param>
/// <param name="algorithm">算法</param>
/// <returns></returns>
public static bool VerifySignature(string orgData, string publicKeyPem, string responseSign, string algorithm)
{
AsymmetricKeyParameter pubKey = GetPublicKeyParameter(publicKeyPem);
byte[] signBytes = Convert.FromBase64String(responseSign);
byte[] plainBytes = Encoding.UTF8.GetBytes(orgData);
ISigner verifier = SignerUtilities.GetSigner(algorithm);
verifier.Init(false, pubKey);
verifier.BlockUpdate(plainBytes, 0, plainBytes.Length);//注意:是byte数组和数组长度,别写成string的长度了
bool isOK = verifier.VerifySignature(signBytes); //验签结果
return isOK;
}
private static AsymmetricKeyParameter GetPublicKeyParameter(string publicKeyPem)
{
//获取公钥纯字符串
publicKeyPem = publicKeyPem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
byte[] publicInfoByte = Convert.FromBase64String(publicKeyPem);
AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);
return pubKey;
}
/// <summary>
/// RSA加密
/// </summary>
/// <param name="orgData">数据</param>
/// <param name="key">私钥、公钥</param>
/// <param name="isPublicKey">是否为公钥</param>
/// <param name="privateKeySize">私钥长度,一般是1024或2048</param>
/// <returns></returns>
public static string EncryptByKey(string orgData, string key, bool isPublicKey, int privateKeySize)
{
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
//加密
//1024长度是117,双方协商好
int maxBlockSize = privateKeySize / 8 - 11; //加密块最大长度限制
engine.Init(true, isPublicKey ? GetPublicKeyParameter(key) : GetPrivateKeyParameter(key));
byte[] byteData = System.Text.Encoding.UTF8.GetBytes(orgData);
int inputLen = byteData.Length;
MemoryStream ms = new MemoryStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0)
{
if (inputLen - offSet > maxBlockSize)
{
cache = engine.ProcessBlock(byteData, offSet, maxBlockSize);
}
else
{
cache = engine.ProcessBlock(byteData, offSet, inputLen - offSet);
}
ms.Write(cache, 0, cache.Length);
i++;
offSet = i * maxBlockSize;
}
byte[] encryptedData = ms.ToArray();
//var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Convert.ToBase64String(encryptedData);
//Console.WriteLine("密文(base64编码):" + Convert.ToBase64String(testData) + Environment.NewLine);
}
/// <summary>
/// RSA解密
/// </summary>
/// <param name="orgData">数据</param>
/// <param name="key">私钥、公钥</param>
/// <param name="isPublicKey">是否为公钥</param>
/// <param name="privateKeySize">私钥长度,一般是1024或2048</param>
/// <returns></returns>
public static string DecryptByKey(string orgData, string key, bool isPublicKey, int privateKeySize)
{
orgData = orgData.Replace("\r", "").Replace("\n", "").Replace(" ", "");
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
//解密
//1024长度是128,双方协商好
int maxBlockSize = privateKeySize / 8; //解密块最大长度限制
engine.Init(false, isPublicKey ? GetPublicKeyParameter(key) : GetPrivateKeyParameter(key));
byte[] byteData = Convert.FromBase64String(orgData);
int inputLen = byteData.Length;
MemoryStream ms = new MemoryStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0)
{
if (inputLen - offSet > maxBlockSize)
{
cache = engine.ProcessBlock(byteData, offSet, maxBlockSize);
}
else
{
cache = engine.ProcessBlock(byteData, offSet, inputLen - offSet);
}
ms.Write(cache, 0, cache.Length);
i++;
offSet = i * maxBlockSize;
}
byte[] encryptedData = ms.ToArray();
//var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Encoding.UTF8.GetString(ms.ToArray());
//Console.WriteLine("密文(base64编码):" + Convert.ToBase64String(testData) + Environment.NewLine);
}
}
}
使用
string formJson = "{\"test\":\"111\"}";
//私钥长度,常用 1024 或 2048
int privateKeySize = 2048;
////公钥加密
string strJiamihou = BCSignUtil.EncryptByKey(formJson, v4_FuYouWxPay.Config.PublicKey, true, privateKeySize);
//私钥解密
string strJiemihou = BCSignUtil.DecryptByKey(strJiamihou, v4_FuYouWxPay.Config.PrivateKey, false, privateKeySize);
网友评论