https://www.bouncycastle.org/csharp/index.html https://github.com/bcgit/bc-csharp
工具类
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
namespace Common.Util
{
public static class RsaUtil
{
/// <summary>
/// 生成密钥对
/// </summary>
/// <param name="privateKey">私钥</param>
/// <param name="publicKey">公钥</param>
public static void CreateKey(out string privateKey, out string publicKey)
{
//RSA密钥对的构造器
RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();
//RSA密钥构造器的参数
RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(BigInteger.ValueOf(3),new SecureRandom(),1024, 25);//密钥长度
//用参数初始化密钥构造器
keyGenerator.Init(param);
//产生密钥对
AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
//获取公钥和密钥
AsymmetricKeyParameter keyPairPublic = keyPair.Public;
AsymmetricKeyParameter keyPairPrivate = keyPair.Private;
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPairPublic);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPairPrivate);
Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();
byte[] publicInfoByte = asn1ObjectPublic.GetEncoded();
publicKey = Convert.ToBase64String(publicInfoByte);
Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded();
privateKey = Convert.ToBase64String(privateInfoByte);
}
public static string Sign(string data, string privateKey, string charset = "utf-8", string signType = "RSA")
{
RSACryptoServiceProvider rsaCsp = DecodePrivateKeyInfo(privateKey, signType);
byte[] dataBytes = null;
if (string.IsNullOrEmpty(charset))
{
dataBytes = Encoding.UTF8.GetBytes(data);
}
else
{
dataBytes = Encoding.GetEncoding(charset).GetBytes(data);
}
HashAlgorithm hash = new SHA1CryptoServiceProvider();
if ("RSA2".Equals(signType))
{
hash = new SHA256CryptoServiceProvider();
}
byte[] signatureBytes = rsaCsp.SignData(dataBytes, hash);
return Convert.ToBase64String(signatureBytes);
}
public static string SignWithMd5(string data, string privateKey, string charset = "utf-8", string signType = "RSA")
{
RSACryptoServiceProvider rsaCsp = DecodePrivateKeyInfo(privateKey, signType);
byte[] dataBytes = null;
if (string.IsNullOrEmpty(charset))
{
dataBytes = Encoding.UTF8.GetBytes(data);
}
else
{
dataBytes = Encoding.GetEncoding(charset).GetBytes(data);
}
byte[] signatureBytes = rsaCsp.SignData(dataBytes, "MD5");
return Convert.ToBase64String(signatureBytes);
}
//public static string Sign(string data, string privateKey, string charset = "utf-8", string signType = "RSA")
//{
// RSACryptoServiceProvider rsaCsp = DecodePrivateKeyInfo(privateKey, signType);
// byte[] dataBytes = null;
// if (string.IsNullOrEmpty(charset))
// {
// dataBytes = Encoding.UTF8.GetBytes(data);
// }
// else
// {
// dataBytes = Encoding.GetEncoding(charset).GetBytes(data);
// }
// HashAlgorithm hash = new SHA1CryptoServiceProvider();
// if ("RSA2".Equals(signType))
// {
// hash = new SHA256CryptoServiceProvider();
// }
// byte[] signatureBytes = rsaCsp.SignData(dataBytes, hash);
// return Convert.ToBase64String(signatureBytes);
//}
public static bool Verify(string data, string publicKeyJava, string signature, string charset = "utf-8", string signType = "RSA")
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKeyJava));
ISigner signer = SignerUtilities.GetSigner("RSA2".Equals(signType) ? "SHA256withRSA" : "SHA1withRSA");
signer.Init(false, publicKeyParam);
byte[] dataByte = Encoding.GetEncoding(charset).GetBytes(data);
signer.BlockUpdate(dataByte, 0, dataByte.Length);
byte[] signatureByte = Convert.FromBase64String(signature);
return signer.VerifySignature(signatureByte);
}
public static bool VerifyWithMd5(string data, string publicKeyJava, string signature)
{
RSACryptoServiceProvider rsaCsp = DecodePublicKey(publicKeyJava);
var result = rsaCsp.VerifyData(Encoding.UTF8.GetBytes(data), "MD5", Convert.FromBase64String(signature));
return result;
}
//public static bool Verify(string data, string publicKey, string signature, string charset = "utf-8", string signType = "RSA")
//{
// //RSACryptoServiceProvider rsaCsp = GetRsaPublicProvider(publicKey);
// RSACryptoServiceProvider rsaCsp = DecodePublicKey(publicKey);
// var encoding = string.IsNullOrEmpty(charset) ? Encoding.UTF8 : Encoding.GetEncoding(charset);
// var dataBytes = encoding.GetBytes(data);
// HashAlgorithm hash = signType== "RSA2" ? new SHA256CryptoServiceProvider() as HashAlgorithm
// : new SHA1CryptoServiceProvider() as HashAlgorithm;
// byte[] signatureBytes = Convert.FromBase64String(signature);
// return rsaCsp.VerifyData(dataBytes, hash, signatureBytes);
//}
//public static string Encrypt(string data, string privateKey, string charset = "utf-8", string signType = "RSA")
//{
// RSACryptoServiceProvider rsaCsp = DecodePrivateKeyInfo(privateKey, signType);
// byte[] dataBytes = null;
// if (string.IsNullOrEmpty(charset))
// {
// dataBytes = Encoding.UTF8.GetBytes(data);
// }
// else
// {
// dataBytes = Encoding.GetEncoding(charset).GetBytes(data);
// }
// var temp = rsaCsp.Encrypt(dataBytes, false);
// var result = Convert.ToBase64String(temp);
// return result;
//}
public static string Encrypt(string data, string publicKey, string charset = "utf-8")
{
RSACryptoServiceProvider rsa = GetRsaPublicProvider(publicKey);
var encoding = string.IsNullOrEmpty(charset) ? Encoding.UTF8 : Encoding.GetEncoding(charset);
encoding = Encoding.UTF8;
var dataBytes = encoding.GetBytes(data);
var temp = rsa.Encrypt(dataBytes, false);
var result = Convert.ToBase64String(temp);
return result;
}
public static string Decrypt(string data, string privateKey, string charset = "utf-8")
{
RSACryptoServiceProvider rsa = GetRsaPrivateProvider(privateKey);
var dataBytes = Convert.FromBase64String(data);
byte[] source = rsa.Decrypt(dataBytes, false);
var encoding = string.IsNullOrEmpty(charset) ? Encoding.UTF8 : Encoding.GetEncoding(charset);
encoding = Encoding.UTF8;
var result = encoding.GetString(source);
return result;
}
public static string EncryptByPrivateKey(string data, string privateKey)
{
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
string result;
try
{
engine.Init(true, GetPrivateKeyParameter(privateKey));
byte[] bytes = Encoding.UTF8.GetBytes(data);
result = Convert.ToBase64String(engine.ProcessBlock(bytes, 0, bytes.Length));
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
public static string DecryptByPublicKey(string data, string publicKey)
{
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
string result;
try
{
engine.Init(false, GetPublicKeyParameter(publicKey));
byte[] byteData = Convert.FromBase64String(data);
byte[] ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
result = Encoding.UTF8.GetString(ResultData);
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
private static AsymmetricKeyParameter GetPublicKeyParameter(string publicKey)
{
publicKey = publicKey.Replace("\r", "").Replace("\n", "").Replace(" ", "");
byte[] bytes = Convert.FromBase64String(publicKey);
Asn1Object.FromByteArray(bytes);
return PublicKeyFactory.CreateKey(bytes);
}
private static AsymmetricKeyParameter GetPrivateKeyParameter(string privateKey)
{
privateKey = privateKey.Replace("\r", "").Replace("\n", "").Replace(" ", "");
return PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
}
public static RSACryptoServiceProvider GetRsaPrivateProvider(string privateKey)
{
RsaPrivateCrtKeyParameters privateKeyParams =
PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)) as RsaPrivateCrtKeyParameters;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters rsaParams = new RSAParameters()
{
Modulus = privateKeyParams.Modulus.ToByteArrayUnsigned(),
Exponent = privateKeyParams.PublicExponent.ToByteArrayUnsigned(),
D = privateKeyParams.Exponent.ToByteArrayUnsigned(),
DP = privateKeyParams.DP.ToByteArrayUnsigned(),
DQ = privateKeyParams.DQ.ToByteArrayUnsigned(),
P = privateKeyParams.P.ToByteArrayUnsigned(),
Q = privateKeyParams.Q.ToByteArrayUnsigned(),
InverseQ = privateKeyParams.QInv.ToByteArrayUnsigned()
};
rsa.ImportParameters(rsaParams);
return rsa;
}
public static RSACryptoServiceProvider GetRsaPublicProvider(string pubilcKey)
{
RsaKeyParameters p =
PublicKeyFactory.CreateKey(Convert.FromBase64String(pubilcKey)) as RsaKeyParameters;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters rsaParams = new RSAParameters
{
Modulus = p.Modulus.ToByteArrayUnsigned(),
Exponent = p.Exponent.ToByteArrayUnsigned()
};
rsa.ImportParameters(rsaParams);
return rsa;
}
/// <summary>
/// 根据私钥生成RSACryptoServiceProvider
/// </summary>
/// <param name="privateKey">私钥</param>
/// <param name="rsaType">RSA类型</param>
/// <returns></returns>
public static RSACryptoServiceProvider DecodePrivateKeyInfo(string privateKey,string rsaType)
{
if (string.IsNullOrEmpty(privateKey))
{
throw new Exception("传入私钥不能为空!");
}
var privateKeyByte = Convert.FromBase64String(privateKey);
byte[] seqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
byte[] seq = new byte[15];
MemoryStream mem = new MemoryStream(privateKeyByte);
int lenstream = (int)mem.Length;
BinaryReader binr = new BinaryReader(mem); ////wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) ////data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); ////advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); ////advance 2 bytes
else
return null;
bt = binr.ReadByte();
if (bt != 0x02)
return null;
twobytes = binr.ReadUInt16();
if (twobytes != 0x0001)
return null;
seq = binr.ReadBytes(15); ////read the Sequence OID
if (!CompareBytearrays(seq, seqOID)) ////make sure Sequence for OID is correct
return null;
bt = binr.ReadByte();
if (bt != 0x04) ////expect an Octet string
return null;
bt = binr.ReadByte(); ////read next byte, or next 2 bytes is 0x81 or 0x82; otherwise bt is the byte count
if (bt == 0x81)
binr.ReadByte();
else
if (bt == 0x82)
binr.ReadUInt16();
////------ at this stage, the remaining sequence should be the RSA private key
byte[] rsaprivkey = binr.ReadBytes((int)(lenstream - mem.Position));
RSACryptoServiceProvider rsacsp = DecodePrivateKey(rsaprivkey, rsaType);
return rsacsp;
}
catch (Exception e)
{
throw e;
}
finally
{
binr.Close();
}
}
private static RSACryptoServiceProvider DecodePrivateKey(byte[] privkey, string rsaType)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
MemoryStream mem = new MemoryStream(privkey);
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
int elems = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return null;
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
return null;
bt = binr.ReadByte();
if (bt != 0x00)
return null;
//------ all private key components are Integer sequences ----
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
D = FixShortageOfArray(binr.ReadBytes(elems), MODULUS.Length);
BitConverter.ToInt64(D, 0);
elems = GetIntegerSize(binr);
P = FixShortageOfArray(binr.ReadBytes(elems), MODULUS.Length / 2);
elems = GetIntegerSize(binr);
Q = FixShortageOfArray(binr.ReadBytes(elems), MODULUS.Length / 2);
elems = GetIntegerSize(binr);
DP = FixShortageOfArray(binr.ReadBytes(elems), MODULUS.Length / 2);
elems = GetIntegerSize(binr);
DQ = FixShortageOfArray(binr.ReadBytes(elems), MODULUS.Length / 2);
elems = GetIntegerSize(binr);
IQ = FixShortageOfArray(binr.ReadBytes(elems), MODULUS.Length / 2);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
CspParameters CspParameters = new CspParameters();
CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
int bitLen = 1024;
if ("RSA2".Equals(rsaType))
{
bitLen = 2048;
}
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(bitLen, CspParameters);
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = MODULUS;
RSAparams.Exponent = E;
RSAparams.D = D;
RSAparams.P = P;
RSAparams.Q = Q;
RSAparams.DP = DP;
RSAparams.DQ = DQ;
RSAparams.InverseQ = IQ;
RSA.ImportParameters(RSAparams);
return RSA;
}
catch (Exception ex)
{
return null;
}
finally
{
binr.Close();
}
}
/// <summary>
/// 根据公钥的Byte[],生成RSACryptoServiceProvider
/// </summary>
/// <param name="publickey">公钥Byte[]</param>
/// <returns></returns>
private static RSACryptoServiceProvider DecodePublicKey(string publicKey)
{
byte[] keyData = Convert.FromBase64String(publicKey);
if (keyData.Length < 162)
{
throw new Exception("公钥Byte[]长度小于162");
}
byte[] pemModulus = new byte[128];
byte[] pemPublicExponent = new byte[3];
try
{
Array.Copy(keyData, 29, pemModulus, 0, 128);
Array.Copy(keyData, 159, pemPublicExponent, 0, 3);
RSAParameters para = new RSAParameters();
para.Modulus = pemModulus;
para.Exponent = pemPublicExponent;
CspParameters CspParameters = new CspParameters();
CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
int bitLen = 1024;
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(bitLen, CspParameters);
RSA.ImportParameters(para);
return RSA;
}
catch (Exception e)
{
throw e;
}
finally
{
}
}
/// <summary>
/// base64 public key string -> xml public key
/// </summary>
/// <param name="pubilcKey"></param>
/// <returns></returns>
public static string ToXmlPublicKey(string pubilcKey)
{
RsaKeyParameters p =
PublicKeyFactory.CreateKey(Convert.FromBase64String(pubilcKey)) as RsaKeyParameters;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
RSAParameters rsaParams = new RSAParameters
{
Modulus = p.Modulus.ToByteArrayUnsigned(),
Exponent = p.Exponent.ToByteArrayUnsigned()
};
rsa.ImportParameters(rsaParams);
return rsa.ToXmlString(false);
}
}
private static bool CompareBytearrays(byte[] a, byte[] b)
{
if (a.Length != b.Length)
return false;
int i = 0;
foreach (byte c in a)
{
if (c != b[i])
return false;
i++;
}
return true;
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02) //expect integer
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
count = binr.ReadByte(); // data size in next byte
else
if (bt == 0x82)
{
highbyte = binr.ReadByte(); // data size in next 2 bytes
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt; // we already have the data size
}
while (binr.ReadByte() == 0x00)
{ //remove high order zeros in data
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte
return count;
}
/// <summary>
/// 修复位数不足的数组
/// </summary>
/// <param name="needFixArray">待修复数组</param>
/// <param name="lenth">正确的位数长度</param>
/// <returns></returns>
private static byte[] FixShortageOfArray(byte[] needFixArray, int lenth)
{
//不需要修复
if (needFixArray.Length == lenth)
{
return needFixArray;
}
else
{
byte[] newArray = new byte[lenth];
Buffer.BlockCopy(needFixArray, 0, newArray, newArray.Length - needFixArray.Length, needFixArray.Length);
return newArray;
}
}
}
}
单元测试
using System;
using System.Web;
using System.Linq;
using System.Text;
using Common.Util;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Test.Util
{
[TestClass]
public class RsaTest
{
[TestMethod]
public void CreateTest()
{
RsaUtil.CreateKey(out string privateKey,out string publicKey);
}
[TestMethod]
public void CertificateSignTest()
{
X509Certificate2 certificate2 = new X509Certificate2("D:\\client34.pfx", "123456");
string privateKey= @"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/lc0yBwq4kbkKJgf0rcJ5mTmnbjOwBVs1U6ZZr/kf8iwgx0e1GSuqlMMAVCMdRSakQbSYgm2KlAs7YKKlH8QiqKfnpZnhIQwpKMWg20OCNA5/e9FoZRH1aRmSc6QV8zopJd2udN0+bFgd4AtMcOZLUOwMwNX7CF5hb+W0iFdEfL1WPYGT1V1QCPleZCbCE1XpJvQcTTBKua4sNsVDbiCd40uFjy1OGEt/7mfO95vCsu/NhWTIUN9En5igvmJ/XpMaz3cuBMPqHjvTQkJpT1On2gzas2JhhUW1vsZC9//wQmuWEVwyoqB3Wx+65vY90mUVqnXzSxx7JlHTzQntGMAhAgMBAAECggEAQXb0qNWTKkJRElCwg0EkpNxgwP99FfaelfhBbYAeBnZ/8atmq1EwhJdUkrYtUYEhlRsGlN5sg9/WfrGkofvaz2UGCrehfzYFq8LM1QxXYxRap+EtSxjOLCd/n3V4ai+0ff78YvJ37y6iZYL7GWGyr6W1Ix55f8/6QB02RpwYBcRqBjlltrYRudwI9I4zMhTqJfdJ6B0nxDmy9gj+vzz37SARd6drBvcYke7xqWskm9tpRCcD5Smr7TdGwOMumSsNpNeJbyH6YqO7So0YkIQE7WCYxdqLLrBVEHvMHm9RCyNnNfQEzJx/G6Ho3LpJcqMccoXTsww17/o/fj+E3jIHiQKBgQDy8+rwq4tF6KFxircjtbXmAm5izsPXDls+ibZcJpbeKIuYgM8Sh91wq1zC+4Q5AnO0GGqfCSJxmNjUvZAqtD9pdlkz2D96htqnLnn9ZqcV7VzsTEQmuXw46THSfBb/GTny16/WOsYGHG00R14a1g2bDk9bi964ggyMLrHeTUU9YwKBgQDJ37A80Ka6dy7MKI3Ob8vLpDfZTl7NKN9k6jljasMaj5b0hmXbARn1uoiAz+urSOCuR78RPUEeO96uNg+EuW32i1JdUqr/2jhg4MVmHu6wcLzBAXHOA0+huJTDvQ3d8geNmjJ8JxUZ7kWA1SXJ29D2gIFT9rVhtRprE++I11P1qwKBgD0suf271CfYOb6TRSYSvSibeBwdICbokIUgu/BcLyTlZLETzhBGcbXLEGJwXozUVzoD4+UDsc6UxBRdXw3BsS3nBPMPAnzhs/DgvQrXbD8TM5C0a3ysu+DApzDu2gOF4JeLQ9VXm0EyqzS8u69aMrbWVZkhkQU4idxKbbMiFcstAoGBAKwkiDdDwXkuGoTTbCEGKiWL8mfmsWaHHQADz04cgyTKHvKDDKYVKVrmZnJZWuBjs9xJp/9+WWH7saaiyNbn/IIJSgH0dYbZQcwyv4GWjPl+GScIIVCIeEYyjQDg3MtPEOvJ+pTuCsti6He0ypV4UZdx+1ZrAT7BXTbD+DWbUKgjAoGAVD4FuWYul7SJ9gNP5Ozu+IliUhnbfrxzw+oneFwAF2Vse1nwdz6kqq0+JfZNhOC553AzX9zZbtzGTzi26D9hh8rOOP8SpJ1Hav6JzVMIQLooyBY/amLgV2N11qgJ9n91NX4o4BcNXXUPr0AkyeSxXmE2zGeXwEbth4svRxH9/+I=";
string publicKey= @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv5XNMgcKuJG5CiYH9K3CeZk5p24zsAVbNVOmWa/5H/IsIMdHtRkrqpTDAFQjHUUmpEG0mIJtipQLO2CipR/EIqin56WZ4SEMKSjFoNtDgjQOf3vRaGUR9WkZknOkFfM6KSXdrnTdPmxYHeALTHDmS1DsDMDV+wheYW/ltIhXRHy9Vj2Bk9VdUAj5XmQmwhNV6Sb0HE0wSrmuLDbFQ24gneNLhY8tThhLf+5nzvebwrLvzYVkyFDfRJ+YoL5if16TGs93LgTD6h4700JCaU9Tp9oM2rNiYYVFtb7GQvf/8EJrlhFcMqKgd1sfuub2PdJlFap180sceyZR080J7RjAIQIDAQAB";
var value = @"certId=1cb30bf9ffcd6615d4c44292894dc6691d0eca22&encoding=UTF-8&legalPersonEdate=2099-12-31&legalPersonIdentityNo=1d63ff61a2c83ee94c30f390d32d52fc497f6ad001db82da69c8ae0df2bc483d&legalPersonName=d7ecc34011e355d97ac04fcaa5ca1389&legalPersonSdate=2018-05-10&licenseEdate=2099-12-31&licenseSdate=2018-05-10&licenseType=2&merAddress=豪威科技大厦一楼排队美食&merCatCode=5812&merCityId=440300&merCreationDate=2018-05-10&merEnglishName=PDMS&merMobile=cb8e86fded5847a89405d28bae10b4cd&merName=排队美食10&merProvinceId=440000&merScope=就餐场所和餐馆(包括快餐)&merShortName=排队美食&merTownId=440305&merType=B&pnrNo=8610284486&receiveAddress=豪威科技大厦一楼排队美食&receiveEmail=f875c1c461782ca043b0355fd1b31822&receiveLinkMan=d7ecc34011e355d97ac04fcaa5ca1389&signMethod=RSA×tamp=1571214971502&version=3.0.4&key=8610284486";
var sign = Convert.ToBase64String(certificate2.GetRSAPrivateKey().SignData(Encoding.UTF8.GetBytes(value), HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1));
var sign2 = RsaUtil.Sign(value, privateKey,signType:"RSA2");
Assert.AreEqual(sign2,sign);
}
[TestMethod]
public void SignTest()
{
string privateKey = @"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJRrRt9KG57PXf5GFtVPWZkX8ZNdAsEMRQJ8dI9/1fCgF6W98RDzFKN9U8m1cPJUQvsNH8EZ+x0FeCe6wiyNGwnUnUVctFcPp4WyqqwTi46jFxcnM5ESddHpriwW437xKf2MwXRoUh4qThvdEunGqzDg4iRPxlvAP29QojGmvfcJAgEDAoGAGLyLz+GvRSKPqmEDzjfkRC6oQzorICy2KxS+F+qjqBqum5+oLX3Yxeo4oZ49fbi11IIv9YRUhNY+sUnLB2zZ1rdoZy8l7exfpVPcH8HbjADoPWAHyAFNj7qoIVGkb6oBS3rN5Dq8sO8XT5PDhsLKwQ7ogYsf5FbyEKG+9hFHJlkCQQDZYVHaBc3mbvOfwMXnluX8M7YOM1GWyf77Zk1fBNeN3TIVH86FzKvKNGFqeN0INUCgCOP3eoyZDvu6nFEnf57/AkEArsmIZ8r1nvqyG8EnoM9goXHw2NGPc9p0jlcWzgQJZ0UGls5MghlMxY3c/ATkLbVp52Y3FYx1HYQPy4wcF5Nx9wJBAJDri+auiURJ97/V2UUPQ/13zrQiNmSGqfzu3j9Yj7PozA4VNFkzHTF4QPGl6LAjgGqwl/pRsxC0p9G9i2+qaf8CQHSGWu/co79RzBKAxRXflcD2oJCLtPfm+F7kud6tW5ouBGSJiFa7iIOz6KgDQskjm++Zeg5do2kCtTJdaA+3oU8CQQDBoYzu1nLR1ZE+MqqgWEPTnwCf6FN7oYG233+lts01ebiW5FXO8XMOPy6Iu83R0lKUjMF6U97+tfGwLJQQd1NI";
var value = "amount=1&appid=wx2cfc213a5b6f76d8&body=测试商品&merchant_code=8886841641&nonce_str=182371781¬ify_url=http://www.liushuqi123456.site/weixin/jhf/notify&openid=oNmgpxF3XJoVIFXBj5-i7HD36QKY&out_trade_no=20210220&pay_way=1";
var sign = RsaUtil.Sign(value, privateKey);
}
[TestMethod]
public void VerifyTest()
{
//string privateKey = string.Empty;
//string publicKey = string.Empty;
//RsaUtil.CreateKey(out privateKey, out publicKey);
string privateKey = @"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIV9Wl4WV4tgaVqUOfpSbcdcpkoGxaiQRdPHtraN2B3NaCr5j+1SXuX+p9zRQlHBAC0+6X25FYyIb08MaOVc0gHSDQE8HndKfBKo4srkCEQ1ONtQCXZzKKGUYHXJviNjUzUsnTgQlJ/HqC+BiU12QaeRYZAROJXWBRBUTWBbsoDRAgMBAAECgYBarc+AUH8Br+mBXWWRFQN7xQU1DiqhGfhFJ8qHcg2YGRuk7ciGd0j9xaJ0DzaU4J1lHvJvtBXeVCQAt7Zd8FK7YoUOKIroyHLSJZwEMwM3ADOW0kxEDG8b+0Y/LSicV8+Ht5Vdjr0DXOUBRlF4UpAJrni+EpHwf1CNgGMR74gwbQJBAPWJnjxRW4nLaMrBq2z2oq7No5xOpgBXKsWJcviwEBJj699W62gKrSl2lfjRpbW3F9aiZcz96oFvuOvjtMMg6ksCQQCLLX1iWDmPexh3r5bKYKtj6c5FHY00ogtWX9l+A+3PVvfKOTvcaNYr5ck+LVIyus41u50vf8PfF4NkhbIXJQ/TAkBpBumxgVd3dJOpjvgFzuW9gebHGHk3UhHQlz+fkqf9RdKCIQrm4RI61yfFW9/W/69ptuN2sPIbVa+y7x7GDJFLAkBdrA9Aupp7HGFaZJ67tRaFl55R3FLmgs3Yo4hRjTlonGMIAz9r2E+VmgG5TG2PYTVa6twfVQGyzDON24ICm9orAkABpI+ZgSYQSzqBiNKKT788hZGY5QZvmg6kSDLf20qLRo86fICoeOGivCSMgT5rEcQTuUTn/QsHy0Fg4pZsbgmS";
string publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCFfVpeFleLYGlalDn6Um3HXKZKBsWokEXTx7a2jdgdzWgq+Y/tUl7l/qfc0UJRwQAtPul9uRWMiG9PDGjlXNIB0g0BPB53SnwSqOLK5AhENTjbUAl2cyihlGB1yb4jY1M1LJ04EJSfx6gvgYlNdkGnkWGQETiV1gUQVE1gW7KA0QIDAQAB";
//var value = "address=豪威科技大厦一楼排队美食&agent_mer_no=8000100098271&bank_branch_name=招商银行总行营业部&bank_city=深圳市&bank_code=308584001024&bank_mer_name=凌晔&bank_name=招商银行&bank_province=广东&cert_type=2&city_no=440300&contact=凌晔&contact_phone=18620331255&district_no=440305&legal_idcard=430204198605194024&legal_idcard_back=f9d94fbcb4cd42ebb8bae7c2a1893273.jpg&legal_idcard_front=0581d34fd0b64388a86a0bb145e294ac.jpg&legal_name=凌晔&license_pic=83698a754f584a10a3b21aebbb3a7020.jpg&mer_type=2&merchant_name=排队美食10&merchant_sub_name=排队美食&product_info=[{\"channel_type\":\"UP_WX\",\"fee_exp\":\"0.0025\"},{\"channel_type\":\"UP_ALIPAY\",\"fee_exp\":\"0.0025\"}]&province_no=440000&request_id=2a249c6ed13548e8be6ac4233a2e1a19&service_phone=18620331255&service_type=xh.uni.merchant.reg&settle_card_no=6225880001401414&settle_type=1&shop_entrance_pic=49f3aac41bd24c90967709c36a3074cc.jpg&version=1.0";
var value = "agent_mer_no=8000100098271&buyer_pay_amount=0.01&buyer_user_id=2088302018893091&channel_type=UP_ALIPAY&fund_bill_list=[{\"amount\":\"0.01\",\"fund_channel\":\"BANKCARD\"}]&merchant_no=8000105201870&out_trade_no=20191111140039&receipt_amount=0.01&rsp_code=0000&rsp_msg=支付成功&time_end=2019-11-11 14:00:44&total_fee=0.01&trx_external_id=10071193770509167366144&trx_status=SUCCESS&version=1.0";
var sign = RsaUtil.Sign(value, privateKey, signType: "RSA2");
var flag = RsaUtil.Verify(value, publicKey, sign, signType: "RSA2");
Assert.AreEqual(true, flag);
var sign1 = RsaUtil.SignWithMd5(value, privateKey, signType: "RSA2");
var flag2 = RsaUtil.VerifyWithMd5(value, publicKey, sign1);
}
[TestMethod]
public void EncryptTest()
{
//string privateKey = string.Empty;
//string publicKey = string.Empty;
//RsaUtil.CreateKey(out privateKey1,out publicKey1);
string privateKey = @"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI/LhgrjSfyhVSQ6Xjfeoty7nWO7/+9/ppBqDwXyCoA2qNleIL9iptDn0wZOM//n81a3hwz8r059vml1gd8tVtIs4jtxByYgcJHbYcQ01iHSAoTzTX46sE/AxQmd9MpIhiXSnfNtrBx/rcBwZOaR0ypLnMqbzb+gV3TEL8OB25l3AgMBAAECgYBJ3wCpr0JfKnKW/fVRNmrsguXEStycqTNklVfKciG65Fmx8Y1ZRND2GWJrptlH6l00e2xB274j0K11eAyUHrKu16MR4Kb79M08uTu3ktSoHxRVPO3OK2My9t9y5baVec88oIboOx0M/lIY7xm1boCDuoVfqmKo618xaMKmFuHcQQJBANxOeCyuuiRk9NgriTLuyt7CEXOwzCkEVfv8zJcfB6Hfg5TsfTk1+jkEhlR49ovTZ+jRdTR7AZkSCfDxEnnpKa8CQQCnF6ENeIj4qQckDmle0ZIb0kl0s1S3qho8WqvhFETDBbjHsB4joeZVY33ssrF1e/x0bSc8a7+YMjB1uC0kO6a5AkBvL9tPEdA4VguMnkxcPFB/JIsSTIR9nwaWavwGuU5s0BXkr4ZzvV5QMIxrTbGA2G10/2Gb3wjrbENAKyscBCVZAkB0AZey/og5+0AV7FuDlQRXhHuzJf4fNV3ZoSnLroK+024iVUfXfUOo7NY0SyuhYV84hb/D1xrB07aJREEy8qchAkEAw3eiSON0FSdgRDl4b+EnJdUfWG77Amh5A6quWbx7LJ8E0QrDiM3qVKexoKPnCnRB1oGJgyy47rrhzmj05Dz4kg==";
string publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPy4YK40n8oVUkOl433qLcu51ju//vf6aQag8F8gqANqjZXiC/YqbQ59MGTjP/5/NWt4cM/K9Ofb5pdYHfLVbSLOI7cQcmIHCR22HENNYh0gKE801+OrBPwMUJnfTKSIYl0p3zbawcf63AcGTmkdMqS5zKm82/oFd0xC/DgduZdwIDAQAB";
var value = "asd";
var encryptStr = RsaUtil.Encrypt(value, publicKey);
var decryptStr = RsaUtil.Decrypt(encryptStr, privateKey);
Assert.AreEqual(value, decryptStr);
//var encryptStr1 = RsaUtil.Encrypt1(value, privateKey);
//var decryptStr1 = RsaUtil.Decrypt1(encryptStr1, publicKey);
var encryptStr1 = RsaUtil.EncryptByPrivateKey(value, privateKey);
var decryptStr1 = RsaUtil.DecryptByPublicKey(encryptStr1, publicKey);
Assert.AreEqual(value, decryptStr1);
}
[TestMethod]
public void asd()
{
//var authUrl = $"FT_CORPID=FTC_PDW&FT_TILEID=05VMC5001&FT_SCENARIO=FTC_PDW05VMC5001001&SYS_TIME={DateTime.Now.ToString("yyyyMMdd HH:mm:ss")}";
//var authUrl = $"FT_CORPID=FTC_PDW&FT_TILEID=05VMC5001&FT_SCENARIO=PDW&SYS_TIME={DateTime.Now.ToString("yyyyMMdd HH:mm:ss")}";
////var authUrl = "FT_CORPID=FTC_PDW&FT_TILEID=05VMC5001&FT_SCENARIO=PDW&SYS_TIME=20210224 16:07:31";
//var key = @"30820154020100300d06092a864886f70d01010105000482013e3082013a020100024100cd01a8b61bb50f72c93ee175f15b3e53a516d7675b765a62749eadf0c157649f9657338c8981a4c91c5f61864e117503a7cd4313650ee854d3824a2bfb73f4830203010001024100b34d8829ff01d58927caff97108a2571332b4f2aef2c0cd19ffe4954114646925d3a11ee5d2f75c79174b6f16308d8d22898f59fb57abac8f645bbbc5c0d22c1022100e8c27a9724f89006355303fa9b513243fefc6cba5cbc937d8fb844bcc5a24c95022100e179c952140c16442ca1362e38c2ec5789c0cd85097d624b58291f9d566edeb702207e49768627330dc1b090f829b2b79d543336f62f2f3dc9b068980c03781f94f902201b01e5756965513d75431224533435eefe5713c6fdae011a194343c02adc38dd022032553430562ea8700e4df68a9a5654a57c6fed3c479de5399223f75f65bbd78d";
//byte[] returnBytes = new byte[key.Length / 2];
//for (int i = 0; i < returnBytes.Length; i++)
//{
// returnBytes[i] = Convert.ToByte(key.Substring(i * 2, 2), 16);
//}
//var privateKey = Convert.ToBase64String(returnBytes);
//var sign = Sign(authUrl, privateKey);
//authUrl += "&SIGN=" + sign;
//var pubKey = "305c300d06092a864886f70d0101010500034b003048024100cd01a8b61bb50f72c93ee175f15b3e53a516d7675b765a62749eadf0c157649f9657338c8981a4c91c5f61864e117503a7cd4313650ee854d3824a2bfb73f4830203010001";
//string ccbParam = HttpUtility.UrlEncode(AESEncrypt(authUrl, pubKey.Substring(pubKey.Length - 32)));
//var sendUrl = "https://static.fcc.ccb.com/CCBIS/ReqCorpAccAuth?FT_CORPID=FTC_PDW&ccbParam=" + ccbParam;
//var result = NetUtil.SendGetRequest(sendUrl);
//var result =
// "{\"SUCCEED\":\"true\",\"ACCESS_TOKEN\":\"WLul+HP3NMaCVd4pCOn1l7Wiw1FJeqiLbqA5TIdhO6hzhEJascNK8SZbX3Z9SeXT4Wl6CBdUXeOXXyva2YEkkO9p+2goDDGbNPAX9tg94Z/Sxh61fX2iGAsTXmvNqxnYUqCXTxC8HM1mD4Imc29mewjYz5ztIEsUvYu8ngYGlnOh83UXNDZc5jiL8AfsLNYWPX3ZFRqMJ68UjmWb5yBxX0xyvmfXbNOpSFvLc0Pdl5A4rrbZ5L/PxfcNBWHD3xe3iIiowJ8zVMsZhTsTFgST3g==\",\"COMMUNICATION_PWD\":\"Q8wvjh8tgrgNKXdGL2s/dNh9l6k42Rgp5mA46ub5TPgYVIsd0dtcIW71khq7L1d9qvsW6gPZ/rV2Kcnz+z+E59uGTOOrcAOXMn6lmJGa0do19VzHNQyasTteDJC/Fb4LHYU7wrBSuxUphm/qjV9b3ene2U4UHduwXgUqDCMZFnwa4Cec3/lgMxeq/qNZvkNEa20ZiN6gVn1HHwRu+7lfnpbMuYkM2p2wPq7ELCYCanj3X/cCL1myII9K0E6nXVqAPKbG2eaOLxhJ4iLHrwnzMHJNNZeBZrdS17sFgkreUrF2edKTIAXBEiadD5Bw0KuyTmK1/7hgDXr16PHcewcIQzAYs+inDANQ6ZJ9kINBpnU=\",\"ACC_ENTRY\":\"https://mapp.dcep.ccb.com/NCCB/MMER10FTMainPlat\",\"EXPIRATION_TIME\":\"2021-03-26 17:39:27\"}";
//result = result.Replace("\'", "\"");
//var dictionary = JsonUtil.JsonToDictionary(result);
//var COMMUNICATION_PWD = dictionary["COMMUNICATION_PWD"];
//var pubKey2 =
// "305c300d06092a864886f70d0101010500034b003048024100a4e530b13157bb468582fbc6e3b88920c5999f1d5c4938bc4ecc9eb12cf57f433f1d3b3a7a053d8b7d45a79f613c61c2b664580b8c635eab63635e9443121c4d0203010001";
//var com = AESDecrypt(COMMUNICATION_PWD, pubKey2.Substring(pubKey2.Length - 32));
//var com1 = com.Substring(0, com.IndexOf("&SYS_TIME="));
var authUrl = $"FT_CORPID=FTC_PDW&FT_TILEID=05VMC5001&FT_SCENARIO=FTC_PDW05VMC5001001&FT_ORDERNO={DateTime.Now.ToString("yyyyMMddHHmmss")}"
+ $"&CUSTOMERID=105000248166077&USERID=REF&PASSWORD=jhf123456"
+ $"&TXCODE=5W5004&LANGUAGE=CN"
+ $"&MONEY=0.01&ORDER=20210301150545" +
$"&REFUND_CODE={DateTime.Now.ToString("yyyyMMddHHmmss")}&Mrch_No=105000248166077";
var comkey = "LOMMOZiW6RojihZ0ZoE7lavuLr7PXe8J";
string ccbParam = HttpUtility.UrlEncode(AESEncrypt(authUrl, comkey));
var baseUrl = "https://mmerchant.ccb.com/NCCB/MMER00FTMainPlat";
var ACCESS_TOKEN2 = "44yTKbCPoyLeE9l+wOeqJHQ7B3LSctjSqus+pJ+rFX4vo/k0XtWIOSR6irbYu4EYUTZqHcOKsOVNl562oVF858Tj10UAj4ZykxvvnlcBj36PT+SWW7YJQSZiApYg1uun4Cugpu+cQtvJ4X88PuKT4zj54I/CTzkD4poCjlgJLmBQhKvjOChACdOgdPptW0Bze3GUIWuVCTb0DujKyhTEScWnFV8XtWG3pWCyXs5OI7TED4gEuUWHicqlXtfyzrqsVjRJvsGvx+DlZ1c/Xnu205ubtLvQnLziJCeHabzaVR4=";
var sendUrl = baseUrl + "?FT_CORPID=FTC_PDW&ccbParam=" + ccbParam + "&ACCESS_TOKEN=" + HttpUtility.UrlEncode(ACCESS_TOKEN2);
var result = NetUtil.SendGetRequest(sendUrl);
var com = AESDecrypt(result, comkey);
}
public static string AESEncrypt(string data, string key)
{
if (string.IsNullOrEmpty(data))
{
return string.Empty;
}
byte[] keyArray = null;
using (var sha1 = new SHA1CryptoServiceProvider())
{
byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(key));
var rd = sha1.ComputeHash(hash);
keyArray = rd.Take(16).ToArray();
}
byte[] plainText = System.Text.Encoding.UTF8.GetBytes(data);
RijndaelManaged AesCipher = new RijndaelManaged();
AesCipher.KeySize = 128;
AesCipher.BlockSize = 128;
AesCipher.Mode = CipherMode.ECB;
AesCipher.Padding = PaddingMode.PKCS7;
AesCipher.Key = keyArray;
ICryptoTransform crypto = AesCipher.CreateEncryptor();
byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length);
var result = Encoding.UTF8.GetString(encode(cipherText));
return result;
}
public static string AESDecrypt(string data, string key)
{
if (string.IsNullOrEmpty(data))
{
return string.Empty;
}
byte[] keyArray = null;
using (var sha1 = new SHA1CryptoServiceProvider())
{
byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(key));
var rd = sha1.ComputeHash(hash);
keyArray = rd.Take(16).ToArray();
}
byte[] plainText = decode(System.Text.Encoding.UTF8.GetBytes(data));
RijndaelManaged AesCipher = new RijndaelManaged();
AesCipher.KeySize = 128;
AesCipher.BlockSize = 128;
AesCipher.Mode = CipherMode.ECB;
AesCipher.Padding = PaddingMode.PKCS7;
AesCipher.Key = keyArray;
ICryptoTransform crypto = AesCipher.CreateDecryptor();
byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length);
var result = Encoding.UTF8.GetString(cipherText);
return result;
}
public string Sign(string data, string privateKey, string charset = "utf-8", string signType = "RSA")
{
RSACryptoServiceProvider rsaCsp = RsaUtil.DecodePrivateKeyInfo(privateKey, signType);
byte[] dataBytes = null;
if (string.IsNullOrEmpty(charset))
{
dataBytes = Encoding.UTF8.GetBytes(data);
}
else
{
dataBytes = Encoding.GetEncoding(charset).GetBytes(data);
}
HashAlgorithm hash = new SHA1CryptoServiceProvider();
if ("RSA2".Equals(signType))
{
hash = new SHA256CryptoServiceProvider();
}
byte[] signatureBytes = rsaCsp.SignData(dataBytes, hash);
var result = bytesToHexStr(encode(signatureBytes));
return result;
return Convert.ToBase64String(signatureBytes);
}
private static byte[] DECODE_TABLE = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56,
57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0 };
private static byte[] ENCODE_TABLE = new byte[] { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43,
47 };
private static char[] bcdLookup = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static byte[] encode(byte[] data)
{
if (data == null)
return null;
int fullGroups = data.Length / 3;
int resultBytes = fullGroups * 4;
if (data.Length % 3 != 0)
resultBytes += 4;
byte[] result = new byte[resultBytes];
int resultIndex = 0;
int dataIndex = 0;
int temp = 0;
for (int i = 0; i < fullGroups; i++)
{
temp = (data[dataIndex++] & 0xff) << 16 | (data[dataIndex++] & 0xff) << 8 | data[dataIndex++] & 0xff;
result[resultIndex++] = ENCODE_TABLE[(temp >> 18) & 0x3f];
result[resultIndex++] = ENCODE_TABLE[(temp >> 12) & 0x3f];
result[resultIndex++] = ENCODE_TABLE[(temp >> 6) & 0x3f];
result[resultIndex++] = ENCODE_TABLE[temp & 0x3f];
}
temp = 0;
while (dataIndex < data.Length)
{
temp <<= 8;
temp |= data[dataIndex++] & 0xff;
}
switch (data.Length % 3)
{
case 1:
temp <<= 8;
temp <<= 8;
result[resultIndex++] = ENCODE_TABLE[(temp >> 18) & 0x3f];
result[resultIndex++] = ENCODE_TABLE[(temp >> 12) & 0x3f];
result[resultIndex++] = 0x3D;
result[resultIndex++] = 0x3D;
break;
case 2:
temp <<= 8;
result[resultIndex++] = ENCODE_TABLE[(temp >> 18) & 0x3f];
result[resultIndex++] = ENCODE_TABLE[(temp >> 12) & 0x3f];
result[resultIndex++] = ENCODE_TABLE[(temp >> 6) & 0x3f];
result[resultIndex++] = 0x3D;
break;
default:
break;
}
return result;
}
public static byte[] decode(byte[] base64Data)
{
if (base64Data == null)
return null;
if (base64Data.Length == 0)
return new byte[0];
if (base64Data.Length % 4 != 0)
throw new ArgumentException("数据不完整,长度为: " + base64Data.Length);
byte[] result = null;
int groupCount = base64Data.Length / 4;
int lastData = base64Data.Length;
while (base64Data[lastData - 1] == 0x3D)
{
if (--lastData == 0)
return new byte[0];
}
result = new byte[lastData - groupCount];
int temp = 0;
int resultIndex = 0;
int dataIndex = 0;
for (; dataIndex + 4 < base64Data.Length;)
{
temp = DECODE_TABLE[base64Data[dataIndex++]];
temp = (temp << 6) + DECODE_TABLE[base64Data[dataIndex++]];
temp = (temp << 6) + DECODE_TABLE[base64Data[dataIndex++]];
temp = (temp << 6) + DECODE_TABLE[base64Data[dataIndex++]];
result[resultIndex++] = (byte)((temp >> 16) & 0xff);
result[resultIndex++] = (byte)((temp >> 8) & 0xff);
result[resultIndex++] = (byte)(temp & 0xff);
}
temp = 0;
int j = 0;
for (; dataIndex < base64Data.Length; dataIndex++, j++)
temp = (temp << 6) + DECODE_TABLE[base64Data[dataIndex]];
for (; j < 4; j++)
temp <<= 6;
result[resultIndex++] = (byte)((temp >> 16) & 0xff);
if (base64Data[dataIndex - 2] != '=')
result[resultIndex++] = (byte)((temp >> 8) & 0xff);
if (base64Data[dataIndex - 1] != '=')
result[resultIndex++] = (byte)(temp & 0xff);
return result;
}
public static string bytesToHexStr(byte[] paramArrayOfByte)
{
StringBuilder localStringBuffer = new StringBuilder(paramArrayOfByte.Length * 2);
for (int i = 0; i < paramArrayOfByte.Length; i++)
{
localStringBuffer.Append(bcdLookup[(paramArrayOfByte[i] >> 4 & 0xF)]);
localStringBuffer.Append(bcdLookup[(paramArrayOfByte[i] & 0xF)]);
}
return localStringBuffer.ToString();
}
}
}