C#SDK提交

This commit is contained in:
tanghc
2019-04-04 16:43:48 +08:00
parent 6c4651115f
commit 40872e1872
20 changed files with 456 additions and 12597 deletions

View File

@@ -1,797 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using SDKCSharp.Common;
namespace SDKCSharp.Utility
{
public class AlipaySignature
{
/** 默认编码字符集 */
private static string DEFAULT_CHARSET = SdkConfig.CHARSET;
public static string GetSignContent(IDictionary<string, string> parameters)
{
// 第一步把字典按Key的字母顺序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder("");
while (dem.MoveNext())
{
string key = dem.Current.Key;
string value = dem.Current.Value;
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
{
query.Append(key).Append("=").Append(value).Append("&");
}
}
string content = query.ToString().Substring(0, query.Length - 1);
return content;
}
public static string RSASign(IDictionary<string, string> parameters, string privateKeyPem, string charset, string signType)
{
string signContent = GetSignContent(parameters);
return RSASignCharSet(signContent, privateKeyPem, charset, signType);
}
public static string RSASign(string data, string privateKeyPem, string charset, string signType)
{
return RSASignCharSet(data, privateKeyPem, charset, signType);
}
///*
public static string RSASign(IDictionary<string, string> parameters, string privateKeyPem, string charset, bool keyFromFile, string signType)
{
string signContent = GetSignContent(parameters);
return RSASignCharSet(signContent, privateKeyPem, charset, keyFromFile, signType);
}
public static string RSASign(string data, string privateKeyPem, string charset, string signType, bool keyFromFile)
{
return RSASignCharSet(data, privateKeyPem, charset, keyFromFile, signType);
}
//*/
public static string RSASignCharSet(string data, string privateKeyPem, string charset, string signType)
{
RSACryptoServiceProvider rsaCsp = LoadCertificateFile(privateKeyPem, signType);
byte[] dataBytes = null;
if (string.IsNullOrEmpty(charset))
{
dataBytes = Encoding.UTF8.GetBytes(data);
}
else
{
dataBytes = Encoding.GetEncoding(charset).GetBytes(data);
}
if ("RSA2".Equals(signType))
{
byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA256");
return Convert.ToBase64String(signatureBytes);
}
else
{
byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");
return Convert.ToBase64String(signatureBytes);
}
}
public static string RSASignCharSet(string data, string privateKeyPem, string charset, bool keyFromFile, string signType)
{
byte[] signatureBytes = null;
try
{
RSACryptoServiceProvider rsaCsp = null;
if (keyFromFile)
{//文件读取
rsaCsp = LoadCertificateFile(privateKeyPem, signType);
}
else
{
//字符串获取
rsaCsp = LoadCertificateString(privateKeyPem, signType);
}
byte[] dataBytes = null;
if (string.IsNullOrEmpty(charset))
{
dataBytes = Encoding.UTF8.GetBytes(data);
}
else
{
dataBytes = Encoding.GetEncoding(charset).GetBytes(data);
}
if (null == rsaCsp)
{
throw new SopException("您使用的私钥格式错误请检查RSA私钥配置" + ",charset = " + charset);
}
if ("RSA2".Equals(signType))
{
signatureBytes = rsaCsp.SignData(dataBytes, "SHA256");
}
else
{
signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");
}
}
catch (Exception ex)
{
throw new SopException("您使用的私钥格式错误请检查RSA私钥配置" + ",charset = " + charset, ex);
}
return Convert.ToBase64String(signatureBytes);
}
public static bool RSACheckV1(IDictionary<string, string> parameters, string publicKeyPem, string charset)
{
string sign = parameters["sign"];
parameters.Remove("sign");
parameters.Remove("sign_type");
string signContent = GetSignContent(parameters);
return RSACheckContent(signContent, sign, publicKeyPem, charset, "RSA");
}
public static bool RSACheckV1(IDictionary<string, string> parameters, string publicKeyPem)
{
string sign = parameters["sign"];
parameters.Remove("sign");
parameters.Remove("sign_type");
string signContent = GetSignContent(parameters);
return RSACheckContent(signContent, sign, publicKeyPem, DEFAULT_CHARSET, "RSA");
}
public static bool RSACheckV1(IDictionary<string, string> parameters, string publicKeyPem, string charset, string signType, bool keyFromFile)
{
string sign = parameters["sign"];
parameters.Remove("sign");
parameters.Remove("sign_type");
string signContent = GetSignContent(parameters);
return RSACheckContent(signContent, sign, publicKeyPem, charset, signType, keyFromFile);
}
public static bool RSACheckV2(IDictionary<string, string> parameters, string publicKeyPem)
{
string sign = parameters["sign"];
parameters.Remove("sign");
string signContent = GetSignContent(parameters);
return RSACheckContent(signContent, sign, publicKeyPem, DEFAULT_CHARSET, "RSA");
}
public static bool RSACheckV2(IDictionary<string, string> parameters, string publicKeyPem, string charset)
{
string sign = parameters["sign"];
parameters.Remove("sign");
string signContent = GetSignContent(parameters);
return RSACheckContent(signContent, sign, publicKeyPem, charset, "RSA");
}
public static bool RSACheckV2(IDictionary<string, string> parameters, string publicKeyPem, string charset, string signType, bool keyFromFile)
{
string sign = parameters["sign"];
parameters.Remove("sign");
string signContent = GetSignContent(parameters);
return RSACheckContent(signContent, sign, publicKeyPem, charset, signType, keyFromFile);
}
public static bool RSACheckContent(string signContent, string sign, string publicKeyPem, string charset, string signType)
{
try
{
if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
if ("RSA2".Equals(signType))
{
string sPublicKeyPEM = File.ReadAllText(publicKeyPem);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.PersistKeyInCsp = false;
RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);
bool bVerifyResultOriginal = rsa.VerifyData(Encoding.GetEncoding(charset).GetBytes(signContent), "SHA256", Convert.FromBase64String(sign));
return bVerifyResultOriginal;
}
else
{
string sPublicKeyPEM = File.ReadAllText(publicKeyPem);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.PersistKeyInCsp = false;
RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
bool bVerifyResultOriginal = rsa.VerifyData(Encoding.GetEncoding(charset).GetBytes(signContent), sha1, Convert.FromBase64String(sign));
return bVerifyResultOriginal;
}
}
catch
{
return false;
}
}
public static bool RSACheckContent(string signContent, string sign, string publicKeyPem, string charset, string signType, bool keyFromFile)
{
try
{
if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
string sPublicKeyPEM;
if (keyFromFile)
{
sPublicKeyPEM = File.ReadAllText(publicKeyPem);
}
else
{
sPublicKeyPEM = "-----BEGIN PUBLIC KEY-----\r\n";
sPublicKeyPEM += publicKeyPem;
sPublicKeyPEM += "-----END PUBLIC KEY-----\r\n\r\n";
}
if ("RSA2".Equals(signType))
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.PersistKeyInCsp = false;
RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);
bool bVerifyResultOriginal = rsa.VerifyData(Encoding.GetEncoding(charset).GetBytes(signContent), "SHA256", Convert.FromBase64String(sign));
return bVerifyResultOriginal;
}
else
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.PersistKeyInCsp = false;
RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
bool bVerifyResultOriginal = rsa.VerifyData(Encoding.GetEncoding(charset).GetBytes(signContent), sha1, Convert.FromBase64String(sign));
return bVerifyResultOriginal;
}
}
catch
{
return false;
}
}
public static bool RSACheckContent(string signContent, string sign, string publicKeyPem, string charset, bool keyFromFile)
{
try
{
string sPublicKeyPEM;
if (keyFromFile)
{
sPublicKeyPEM = File.ReadAllText(publicKeyPem);
}
else
{
sPublicKeyPEM = "-----BEGIN PUBLIC KEY-----\r\n";
sPublicKeyPEM = sPublicKeyPEM + publicKeyPem;
sPublicKeyPEM = sPublicKeyPEM + "-----END PUBLIC KEY-----\r\n\r\n";
}
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.PersistKeyInCsp = false;
RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
bool bVerifyResultOriginal = rsa.VerifyData(Encoding.GetEncoding(charset).GetBytes(signContent), sha1, Convert.FromBase64String(sign));
return bVerifyResultOriginal;
}
catch (Exception ex)
{
string s = ex.Message.ToString();
return false;
}
}
public static string CheckSignAndDecrypt(IDictionary<string, string> parameters, string alipayPublicKey,
string cusPrivateKey, bool isCheckSign,
bool isDecrypt)
{
string charset = parameters["charset"];
string bizContent = parameters["biz_content"];
if (isCheckSign)
{
if (!RSACheckV2(parameters, alipayPublicKey, charset))
{
throw new SopException("rsaCheck failure:rsaParams=" + parameters);
}
}
if (isDecrypt)
{
return RSADecrypt(bizContent, cusPrivateKey, charset, "RSA");
}
return bizContent;
}
public static string CheckSignAndDecrypt(IDictionary<string, string> parameters, string alipayPublicKey,
string cusPrivateKey, bool isCheckSign,
bool isDecrypt, string signType, bool keyFromFile)
{
string charset = parameters["charset"];
string bizContent = parameters["biz_content"];
if (isCheckSign)
{
if (!RSACheckV2(parameters, alipayPublicKey, charset, signType, keyFromFile))
{
throw new SopException("rsaCheck failure:rsaParams=" + parameters);
}
}
if (isDecrypt)
{
return RSADecrypt(bizContent, cusPrivateKey, charset, signType ,keyFromFile);
}
return bizContent;
}
public static string encryptAndSign(string bizContent, string alipayPublicKey,
string cusPrivateKey, string charset, bool isEncrypt,
bool isSign, string signType, bool keyFromFile)
{
StringBuilder sb = new StringBuilder();
if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
sb.Append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>");
if (isEncrypt)
{// 加密
sb.Append("<alipay>");
String encrypted = RSAEncrypt(bizContent, alipayPublicKey, charset, keyFromFile);
sb.Append("<response>" + encrypted + "</response>");
sb.Append("<encryption_type>"+signType+"</encryption_type>");
if (isSign)
{
String sign = RSASign(encrypted, cusPrivateKey, charset, signType, keyFromFile);
sb.Append("<sign>" + sign + "</sign>");
sb.Append("<sign_type>"+signType+"</sign_type>");
}
sb.Append("</alipay>");
}
else if (isSign)
{// 不加密,但需要签名
sb.Append("<alipay>");
sb.Append("<response>" + bizContent + "</response>");
String sign = RSASign(bizContent, cusPrivateKey, charset, signType, keyFromFile);
sb.Append("<sign>" + sign + "</sign>");
sb.Append("<sign_type>"+signType+"</sign_type>");
sb.Append("</alipay>");
}
else
{// 不加密,不加签
sb.Append(bizContent);
}
return sb.ToString();
}
public static string encryptAndSign(string bizContent, string alipayPublicKey,
string cusPrivateKey, string charset, bool isEncrypt,
bool isSign)
{
StringBuilder sb = new StringBuilder();
if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
sb.Append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>");
if (isEncrypt)
{// 加密
sb.Append("<alipay>");
String encrypted = RSAEncrypt(bizContent, alipayPublicKey, charset);
sb.Append("<response>" + encrypted + "</response>");
sb.Append("<encryption_type>RSA</encryption_type>");
if (isSign)
{
String sign = RSASign(encrypted, cusPrivateKey, charset, "RSA");
sb.Append("<sign>" + sign + "</sign>");
sb.Append("<sign_type>RSA</sign_type>");
}
sb.Append("</alipay>");
}
else if (isSign)
{// 不加密,但需要签名
sb.Append("<alipay>");
sb.Append("<response>" + bizContent + "</response>");
String sign = RSASign(bizContent, cusPrivateKey, charset, "RSA");
sb.Append("<sign>" + sign + "</sign>");
sb.Append("<sign_type>RSA</sign_type>");
sb.Append("</alipay>");
}
else
{// 不加密,不加签
sb.Append(bizContent);
}
return sb.ToString();
}
public static string RSAEncrypt(string content, string publicKeyPem, string charset)
{
try
{
string sPublicKeyPEM = File.ReadAllText(publicKeyPem);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.PersistKeyInCsp = false;
RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);
if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
byte[] data = Encoding.GetEncoding(charset).GetBytes(content);
int maxBlockSize = rsa.KeySize / 8 - 11; //加密块最大长度限制
if (data.Length <= maxBlockSize)
{
byte[] cipherbytes = rsa.Encrypt(data, false);
return Convert.ToBase64String(cipherbytes);
}
MemoryStream plaiStream = new MemoryStream(data);
MemoryStream crypStream = new MemoryStream();
Byte[] buffer = new Byte[maxBlockSize];
int blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
while (blockSize > 0)
{
Byte[] toEncrypt = new Byte[blockSize];
Array.Copy(buffer, 0, toEncrypt, 0, blockSize);
Byte[] cryptograph = rsa.Encrypt(toEncrypt, false);
crypStream.Write(cryptograph, 0, cryptograph.Length);
blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
}
return Convert.ToBase64String(crypStream.ToArray(), Base64FormattingOptions.None);
}
catch (Exception ex)
{
throw new SopException("EncryptContent = " + content + ",charset = " + charset, ex);
}
}
public static string RSAEncrypt(string content, string publicKeyPem, string charset, bool keyFromFile)
{
try
{
string sPublicKeyPEM;
if (keyFromFile) {
sPublicKeyPEM = File.ReadAllText(publicKeyPem);
}else{
sPublicKeyPEM = "-----BEGIN PUBLIC KEY-----\r\n";
sPublicKeyPEM += publicKeyPem;
sPublicKeyPEM += "-----END PUBLIC KEY-----\r\n\r\n";
}
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.PersistKeyInCsp = false;
RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);
if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
byte[] data = Encoding.GetEncoding(charset).GetBytes(content);
int maxBlockSize = rsa.KeySize / 8 - 11; //加密块最大长度限制
if (data.Length <= maxBlockSize)
{
byte[] cipherbytes = rsa.Encrypt(data, false);
return Convert.ToBase64String(cipherbytes);
}
MemoryStream plaiStream = new MemoryStream(data);
MemoryStream crypStream = new MemoryStream();
Byte[] buffer = new Byte[maxBlockSize];
int blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
while (blockSize > 0)
{
Byte[] toEncrypt = new Byte[blockSize];
Array.Copy(buffer, 0, toEncrypt, 0, blockSize);
Byte[] cryptograph = rsa.Encrypt(toEncrypt, false);
crypStream.Write(cryptograph, 0, cryptograph.Length);
blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
}
return Convert.ToBase64String(crypStream.ToArray(), Base64FormattingOptions.None);
}
catch (Exception ex)
{
throw new SopException("EncryptContent = " + content + ",charset = " + charset, ex);
}
}
public static string RSADecrypt(string content, string privateKeyPem, string charset, string signType)
{
try
{
RSACryptoServiceProvider rsaCsp = LoadCertificateFile(privateKeyPem, signType);
if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
byte[] data = Convert.FromBase64String(content);
int maxBlockSize = rsaCsp.KeySize / 8; //解密块最大长度限制
if (data.Length <= maxBlockSize)
{
byte[] cipherbytes = rsaCsp.Decrypt(data, false);
return Encoding.GetEncoding(charset).GetString(cipherbytes);
}
MemoryStream crypStream = new MemoryStream(data);
MemoryStream plaiStream = new MemoryStream();
Byte[] buffer = new Byte[maxBlockSize];
int blockSize = crypStream.Read(buffer, 0, maxBlockSize);
while (blockSize > 0)
{
Byte[] toDecrypt = new Byte[blockSize];
Array.Copy(buffer, 0, toDecrypt, 0, blockSize);
Byte[] cryptograph = rsaCsp.Decrypt(toDecrypt, false);
plaiStream.Write(cryptograph, 0, cryptograph.Length);
blockSize = crypStream.Read(buffer, 0, maxBlockSize);
}
return Encoding.GetEncoding(charset).GetString(plaiStream.ToArray());
}
catch (Exception ex)
{
throw new SopException("DecryptContent = " + content + ",charset = " + charset, ex);
}
}
public static string RSADecrypt(string content, string privateKeyPem, string charset, string signType, bool keyFromFile)
{
try
{
RSACryptoServiceProvider rsaCsp = null;
if (keyFromFile)
{
//文件读取
rsaCsp = LoadCertificateFile(privateKeyPem, signType);
}
else
{
//字符串获取
rsaCsp = LoadCertificateString(privateKeyPem, signType);
}
if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
byte[] data = Convert.FromBase64String(content);
int maxBlockSize = rsaCsp.KeySize / 8; //解密块最大长度限制
if (data.Length <= maxBlockSize)
{
byte[] cipherbytes = rsaCsp.Decrypt(data, false);
return Encoding.GetEncoding(charset).GetString(cipherbytes);
}
MemoryStream crypStream = new MemoryStream(data);
MemoryStream plaiStream = new MemoryStream();
Byte[] buffer = new Byte[maxBlockSize];
int blockSize = crypStream.Read(buffer, 0, maxBlockSize);
while (blockSize > 0)
{
Byte[] toDecrypt = new Byte[blockSize];
Array.Copy(buffer, 0, toDecrypt, 0, blockSize);
Byte[] cryptograph = rsaCsp.Decrypt(toDecrypt, false);
plaiStream.Write(cryptograph, 0, cryptograph.Length);
blockSize = crypStream.Read(buffer, 0, maxBlockSize);
}
return Encoding.GetEncoding(charset).GetString(plaiStream.ToArray());
}
catch (Exception ex)
{
throw new SopException("DecryptContent = " + content + ",charset = " + charset, ex);
}
}
private static byte[] GetPem(string type, byte[] data)
{
string pem = Encoding.UTF8.GetString(data);
string header = String.Format("-----BEGIN {0}-----\\n", type);
string footer = String.Format("-----END {0}-----", type);
int start = pem.IndexOf(header) + header.Length;
int end = pem.IndexOf(footer, start);
string base64 = pem.Substring(start, (end - start));
return Convert.FromBase64String(base64);
}
// 加载秘钥文件
private static RSACryptoServiceProvider LoadCertificateFile(string filename, string signType)
{
using (System.IO.FileStream fs = System.IO.File.OpenRead(filename))
{
byte[] data = new byte[fs.Length];
byte[] res = null;
fs.Read(data, 0, data.Length);
if (data[0] != 0x30)
{
res = GetPem("RSA PRIVATE KEY", data);
}
try
{
RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(res, signType);
return rsa;
}
catch (Exception ex)
{
throw new SopException("LoadCertificateFile fail", ex);
}
}
}
private static RSACryptoServiceProvider LoadCertificateString(string strKey, string signType)
{
byte[] data = null;
//读取带
//ata = Encoding.Default.GetBytes(strKey);
data = Convert.FromBase64String(strKey);
//data = GetPem("RSA PRIVATE KEY", data);
try
{
RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(data, signType);
return rsa;
}
catch (Exception ex)
{
throw new SopException("DecodeRSAPrivateKey fail", ex);
}
}
private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey, string signType)
{
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 = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
P = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
Q = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DP = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DQ = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
CspParameters CspParameters = new CspParameters();
CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
int bitLen = 1024;
if ("RSA2".Equals(signType))
{
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)
{
throw new SopException("DecodeRSAPrivateKey fail" + ex.Message, ex);
}
finally
{
binr.Close();
}
}
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;
}
}
}

View File

@@ -1,210 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
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.Crypto.Engines;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto.Encodings;
namespace SDKCSharp.Utility
{
public class RSA
{
private static Encoding Encoding_UTF8 = Encoding.UTF8;
/// <summary>
/// KEY 结构体
/// </summary>
public struct RSAKEY
{
/// <summary>
/// 公钥
/// </summary>
public string PublicKey
{
get;
set;
}
/// <summary>
/// 私钥
/// </summary>
public string PrivateKey
{
get;
set;
}
}
public RSAKEY GetKey()
{
//RSA密钥对的构造器
RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();
//RSA密钥构造器的参数
RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
Org.BouncyCastle.Math.BigInteger.ValueOf(3),
new Org.BouncyCastle.Security.SecureRandom(),
1024, //密钥长度
25);
//用参数初始化密钥构造器
keyGenerator.Init(param);
//产生密钥对
AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
//获取公钥和密钥
AsymmetricKeyParameter publicKey = keyPair.Public;
AsymmetricKeyParameter privateKey = keyPair.Private;
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();
byte[] publicInfoByte = asn1ObjectPublic.GetEncoded("UTF-8");
Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded("UTF-8");
RSAKEY item = new RSAKEY()
{
PublicKey = Convert.ToBase64String(publicInfoByte),
PrivateKey = Convert.ToBase64String(privateInfoByte)
};
return item;
}
private AsymmetricKeyParameter GetPublicKeyParameter(string keyBase64)
{
keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", "");
byte[] publicInfoByte = Convert.FromBase64String(keyBase64);
Asn1Object pubKeyObj = Asn1Object.FromByteArray(publicInfoByte);//这里也可以从流中读取,从本地导入
AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);
return pubKey;
}
private AsymmetricKeyParameter GetPrivateKeyParameter(string keyBase64)
{
keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", "");
byte[] privateInfoByte = Convert.FromBase64String(keyBase64);
// Asn1Object priKeyObj = Asn1Object.FromByteArray(privateInfoByte);//这里也可以从流中读取,从本地导入
// PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
return priKey;
}
/// <summary>
/// 私钥加密
/// </summary>
/// <param name="data">加密内容</param>
/// <param name="privateKey">私钥Base64后的</param>
/// <returns>返回Base64内容</returns>
public string EncryptByPrivateKey(string data, string privateKey)
{
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
//加密
try
{
engine.Init(true, GetPrivateKeyParameter(privateKey));
byte[] byteData = Encoding_UTF8.GetBytes(data);
var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Convert.ToBase64String(ResultData);
//Console.WriteLine("密文base64编码:" + Convert.ToBase64String(testData) + Environment.NewLine);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 私钥解密
/// </summary>
/// <param name="data">待解密的内容</param>
/// <param name="privateKey">私钥Base64编码后的</param>
/// <returns>返回明文</returns>
public string DecryptByPrivateKey(string data, string privateKey)
{
data = data.Replace("\r", "").Replace("\n", "").Replace(" ", "");
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
//解密
try
{
engine.Init(false, GetPrivateKeyParameter(privateKey));
byte[] byteData = Convert.FromBase64String(data);
var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Encoding_UTF8.GetString(ResultData);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 公钥加密
/// </summary>
/// <param name="data">加密内容</param>
/// <param name="publicKey">公钥Base64编码后的</param>
/// <returns>返回Base64内容</returns>
public string EncryptByPublicKey(string data, string publicKey)
{
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
//加密
try
{
engine.Init(true, GetPublicKeyParameter(publicKey));
byte[] byteData = Encoding_UTF8.GetBytes(data);
var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Convert.ToBase64String(ResultData);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 公钥解密
/// </summary>
/// <param name="data">待解密的内容</param>
/// <param name="publicKey">公钥Base64编码后的</param>
/// <returns>返回明文</returns>
public string DecryptByPublicKey(string data, string publicKey)
{
data = data.Replace("\r", "").Replace("\n", "").Replace(" ", "");
//非对称加密算法,加解密用
IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
//解密
try
{
engine.Init(false, GetPublicKeyParameter(publicKey));
byte[] byteData = Convert.FromBase64String(data);
var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
return Encoding_UTF8.GetString(ResultData);
}
catch (Exception ex)
{
throw ex;
}
}
}
}

View File

@@ -1,245 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.IO;
namespace SDKCSharp.Utility
{
public static class RSACryptoServiceProviderExtension
{
#region Methods
/// <summary>Extension method which initializes an RSACryptoServiceProvider from a DER public key blob.</summary>
public static void LoadPublicKeyDER( RSACryptoServiceProvider provider, byte[] DERData )
{
byte[] RSAData = RSACryptoServiceProviderExtension.GetRSAFromDER( DERData );
byte[] publicKeyBlob = RSACryptoServiceProviderExtension.GetPublicKeyBlobFromRSA( RSAData );
provider.ImportCspBlob( publicKeyBlob );
}
/// <summary>Extension method which initializes an RSACryptoServiceProvider from a PEM public key string.</summary>
public static void LoadPublicKeyPEM( RSACryptoServiceProvider provider, string sPEM )
{
byte[] DERData = RSACryptoServiceProviderExtension.GetDERFromPEM( sPEM );
RSACryptoServiceProviderExtension.LoadPublicKeyDER( provider, DERData );
}
/// <summary>Returns a public key blob from an RSA public key.</summary>
internal static byte[] GetPublicKeyBlobFromRSA( byte[] RSAData )
{
byte[] data = null;
UInt32 dwCertPublicKeyBlobSize = 0;
if ( RSACryptoServiceProviderExtension.CryptDecodeObject( CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
new IntPtr( (int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB ), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
data, ref dwCertPublicKeyBlobSize ) )
{
data = new byte[ dwCertPublicKeyBlobSize ];
if ( !RSACryptoServiceProviderExtension.CryptDecodeObject( CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
new IntPtr( (int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB ), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
data, ref dwCertPublicKeyBlobSize ) )
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
else
throw new Win32Exception( Marshal.GetLastWin32Error() );
return data;
}
/// <summary>Converts DER binary format to a CAPI CERT_PUBLIC_KEY_INFO structure containing an RSA key.</summary>
internal static byte[] GetRSAFromDER( byte[] DERData )
{
byte[] data = null;
byte[] publicKey = null;
CERT_PUBLIC_KEY_INFO info;
UInt32 dwCertPublicKeyInfoSize = 0;
IntPtr pCertPublicKeyInfo = IntPtr.Zero;
if ( RSACryptoServiceProviderExtension.CryptDecodeObject( CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr( (int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO ),
DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize ) )
{
data = new byte[ dwCertPublicKeyInfoSize ];
if ( RSACryptoServiceProviderExtension.CryptDecodeObject( CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr( (int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO ),
DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize ) )
{
GCHandle handle = GCHandle.Alloc( data, GCHandleType.Pinned );
try
{
info = (CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure( handle.AddrOfPinnedObject(), typeof( CERT_PUBLIC_KEY_INFO ) );
publicKey = new byte[ info.PublicKey.cbData ];
Marshal.Copy( info.PublicKey.pbData, publicKey, 0, publicKey.Length );
}
finally
{
handle.Free();
}
}
else
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
else
throw new Win32Exception( Marshal.GetLastWin32Error() );
return publicKey;
}
/// <summary>Extracts the binary data from a PEM file.</summary>
internal static byte[] GetDERFromPEM( string sPEM )
{
UInt32 dwSkip, dwFlags;
UInt32 dwBinarySize = 0;
if ( !RSACryptoServiceProviderExtension.CryptStringToBinary( sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, null, ref dwBinarySize, out dwSkip, out dwFlags ) )
throw new Win32Exception( Marshal.GetLastWin32Error() );
byte[] decodedData = new byte[ dwBinarySize ];
if ( !RSACryptoServiceProviderExtension.CryptStringToBinary( sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, decodedData, ref dwBinarySize, out dwSkip, out dwFlags ) )
throw new Win32Exception( Marshal.GetLastWin32Error() );
return decodedData;
}
#endregion Methods
#region P/Invoke Constants
/// <summary>Enumeration derived from Crypto API.</summary>
internal enum CRYPT_ACQUIRE_CONTEXT_FLAGS : uint
{
CRYPT_NEWKEYSET = 0x8,
CRYPT_DELETEKEYSET = 0x10,
CRYPT_MACHINE_KEYSET = 0x20,
CRYPT_SILENT = 0x40,
CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x80,
CRYPT_VERIFYCONTEXT = 0xF0000000
}
/// <summary>Enumeration derived from Crypto API.</summary>
internal enum CRYPT_PROVIDER_TYPE : uint
{
PROV_RSA_FULL = 1
}
/// <summary>Enumeration derived from Crypto API.</summary>
internal enum CRYPT_DECODE_FLAGS : uint
{
NONE = 0,
CRYPT_DECODE_ALLOC_FLAG = 0x8000
}
/// <summary>Enumeration derived from Crypto API.</summary>
internal enum CRYPT_ENCODING_FLAGS : uint
{
PKCS_7_ASN_ENCODING = 0x00010000,
X509_ASN_ENCODING = 0x00000001,
}
/// <summary>Enumeration derived from Crypto API.</summary>
internal enum CRYPT_OUTPUT_TYPES : int
{
X509_PUBLIC_KEY_INFO = 8,
RSA_CSP_PUBLICKEYBLOB = 19,
PKCS_RSA_PRIVATE_KEY = 43,
PKCS_PRIVATE_KEY_INFO = 44
}
/// <summary>Enumeration derived from Crypto API.</summary>
internal enum CRYPT_STRING_FLAGS : uint
{
CRYPT_STRING_BASE64HEADER = 0,
CRYPT_STRING_BASE64 = 1,
CRYPT_STRING_BINARY = 2,
CRYPT_STRING_BASE64REQUESTHEADER = 3,
CRYPT_STRING_HEX = 4,
CRYPT_STRING_HEXASCII = 5,
CRYPT_STRING_BASE64_ANY = 6,
CRYPT_STRING_ANY = 7,
CRYPT_STRING_HEX_ANY = 8,
CRYPT_STRING_BASE64X509CRLHEADER = 9,
CRYPT_STRING_HEXADDR = 10,
CRYPT_STRING_HEXASCIIADDR = 11,
CRYPT_STRING_HEXRAW = 12,
CRYPT_STRING_NOCRLF = 0x40000000,
CRYPT_STRING_NOCR = 0x80000000
}
#endregion P/Invoke Constants
#region P/Invoke Structures
/// <summary>Structure from Crypto API.</summary>
[StructLayout( LayoutKind.Sequential )]
internal struct CRYPT_OBJID_BLOB
{
internal UInt32 cbData;
internal IntPtr pbData;
}
/// <summary>Structure from Crypto API.</summary>
[StructLayout( LayoutKind.Sequential )]
internal struct CRYPT_ALGORITHM_IDENTIFIER
{
internal IntPtr pszObjId;
internal CRYPT_OBJID_BLOB Parameters;
}
/// <summary>Structure from Crypto API.</summary>
[StructLayout( LayoutKind.Sequential )]
struct CRYPT_BIT_BLOB
{
internal UInt32 cbData;
internal IntPtr pbData;
internal UInt32 cUnusedBits;
}
/// <summary>Structure from Crypto API.</summary>
[StructLayout( LayoutKind.Sequential )]
struct CERT_PUBLIC_KEY_INFO
{
internal CRYPT_ALGORITHM_IDENTIFIER Algorithm;
internal CRYPT_BIT_BLOB PublicKey;
}
#endregion P/Invoke Structures
#region P/Invoke Functions
/// <summary>Function for Crypto API.</summary>
[DllImport( "advapi32.dll", SetLastError = true )]
[return: MarshalAs( UnmanagedType.Bool )]
internal static extern bool CryptDestroyKey( IntPtr hKey );
/// <summary>Function for Crypto API.</summary>
[DllImport( "advapi32.dll", SetLastError = true )]
[return: MarshalAs( UnmanagedType.Bool )]
internal static extern bool CryptImportKey( IntPtr hProv, byte[] pbKeyData, UInt32 dwDataLen, IntPtr hPubKey, UInt32 dwFlags, ref IntPtr hKey );
/// <summary>Function for Crypto API.</summary>
[DllImport( "advapi32.dll", SetLastError = true )]
[return: MarshalAs( UnmanagedType.Bool )]
internal static extern bool CryptReleaseContext( IntPtr hProv, Int32 dwFlags );
/// <summary>Function for Crypto API.</summary>
[DllImport( "advapi32.dll", CharSet = CharSet.Auto, SetLastError = true )]
[return: MarshalAs( UnmanagedType.Bool )]
internal static extern bool CryptAcquireContext( ref IntPtr hProv, string pszContainer, string pszProvider, CRYPT_PROVIDER_TYPE dwProvType, CRYPT_ACQUIRE_CONTEXT_FLAGS dwFlags );
/// <summary>Function from Crypto API.</summary>
[DllImport( "crypt32.dll", SetLastError = true, CharSet = CharSet.Auto )]
[return: MarshalAs( UnmanagedType.Bool )]
internal static extern bool CryptStringToBinary( string sPEM, UInt32 sPEMLength, CRYPT_STRING_FLAGS dwFlags, [Out] byte[] pbBinary, ref UInt32 pcbBinary, out UInt32 pdwSkip, out UInt32 pdwFlags );
/// <summary>Function from Crypto API.</summary>
[DllImport( "crypt32.dll", SetLastError = true )]
[return: MarshalAs( UnmanagedType.Bool )]
internal static extern bool CryptDecodeObjectEx( CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS dwFlags, IntPtr pDecodePara, ref byte[] pvStructInfo, ref UInt32 pcbStructInfo );
/// <summary>Function from Crypto API.</summary>
[DllImport( "crypt32.dll", SetLastError = true )]
[return: MarshalAs( UnmanagedType.Bool )]
internal static extern bool CryptDecodeObject( CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS flags, [In, Out] byte[] pvStructInfo, ref UInt32 cbStructInfo );
#endregion P/Invoke Functions
}
}

View File

@@ -0,0 +1,296 @@
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace SDKCSharp.Utility
{
public class RSAHelper
{
private readonly RSA _privateKeyRsaProvider;
private readonly RSA _publicKeyRsaProvider;
private readonly HashAlgorithmName _hashAlgorithmName;
private readonly Encoding _encoding;
/// <summary>
/// 实例化RSAHelper
/// </summary>
/// <param name="signType">加密算法类型 RSA SHA1;RSA2 SHA256 密钥长度至少为2048</param>
/// <param name="encoding">编码类型</param>
/// <param name="privateKey">私钥</param>
/// <param name="publicKey">公钥</param>
public RSAHelper(SignType signType, Encoding encoding, string privateKey, string publicKey = null)
{
_encoding = encoding;
if (!string.IsNullOrEmpty(privateKey))
{
_privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey);
}
if (!string.IsNullOrEmpty(publicKey))
{
_publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey);
}
_hashAlgorithmName = signType == SignType.RSA ? HashAlgorithmName.SHA1 : HashAlgorithmName.SHA256;
}
#region 使
/// <summary>
/// 使用私钥签名
/// </summary>
/// <param name="data">原始数据</param>
/// <returns></returns>
public string Sign(string data)
{
byte[] dataBytes = _encoding.GetBytes(data);
var signatureBytes = _privateKeyRsaProvider.SignData(dataBytes, _hashAlgorithmName, RSASignaturePadding.Pkcs1);
return Convert.ToBase64String(signatureBytes);
}
#endregion
#region 使
/// <summary>
/// 使用公钥验证签名
/// </summary>
/// <param name="data">原始数据</param>
/// <param name="sign">签名</param>
/// <returns></returns>
public bool Verify(string data, string sign)
{
byte[] dataBytes = _encoding.GetBytes(data);
byte[] signBytes = Convert.FromBase64String(sign);
var verify = _publicKeyRsaProvider.VerifyData(dataBytes, signBytes, _hashAlgorithmName, RSASignaturePadding.Pkcs1);
return verify;
}
#endregion
#region
public string Decrypt(string cipherText)
{
if (_privateKeyRsaProvider == null)
{
throw new Exception("_privateKeyRsaProvider is null");
}
return Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(Convert.FromBase64String(cipherText), RSAEncryptionPadding.Pkcs1));
}
#endregion
#region
public string Encrypt(string text)
{
if (_publicKeyRsaProvider == null)
{
throw new Exception("_publicKeyRsaProvider is null");
}
return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), RSAEncryptionPadding.Pkcs1));
}
#endregion
#region 使RSA实例
public RSA CreateRsaProviderFromPrivateKey(string privateKey)
{
var privateKeyBits = Convert.FromBase64String(privateKey);
var rsa = RSA.Create();
var rsaParameters = new RSAParameters();
using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))
{
byte bt = 0;
ushort twobytes = 0;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130)
binr.ReadByte();
else if (twobytes == 0x8230)
binr.ReadInt16();
else
throw new Exception("Unexpected value read binr.ReadUInt16()");
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102)
throw new Exception("Unexpected version");
bt = binr.ReadByte();
if (bt != 0x00)
throw new Exception("Unexpected value read binr.ReadByte()");
rsaParameters.Modulus = binr.ReadBytes(GetIntegerSize(binr));
rsaParameters.Exponent = binr.ReadBytes(GetIntegerSize(binr));
rsaParameters.D = binr.ReadBytes(GetIntegerSize(binr));
rsaParameters.P = binr.ReadBytes(GetIntegerSize(binr));
rsaParameters.Q = binr.ReadBytes(GetIntegerSize(binr));
rsaParameters.DP = binr.ReadBytes(GetIntegerSize(binr));
rsaParameters.DQ = binr.ReadBytes(GetIntegerSize(binr));
rsaParameters.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
}
rsa.ImportParameters(rsaParameters);
return rsa;
}
#endregion
#region 使RSA实例
public RSA CreateRsaProviderFromPublicKey(string publicKeyString)
{
// encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
byte[] seqOid = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
byte[] seq = new byte[15];
var x509Key = Convert.FromBase64String(publicKeyString);
// --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------
using (MemoryStream mem = new MemoryStream(x509Key))
{
using (BinaryReader binr = new BinaryReader(mem)) //wrap Memory Stream with BinaryReader for easy reading
{
byte bt = 0;
ushort twobytes = 0;
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;
seq = binr.ReadBytes(15); //read the Sequence OID
if (!CompareBytearrays(seq, seqOid)) //make sure Sequence for OID is correct
return null;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8203)
binr.ReadInt16(); //advance 2 bytes
else
return null;
bt = binr.ReadByte();
if (bt != 0x00) //expect null byte next
return null;
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();
byte lowbyte = 0x00;
byte highbyte = 0x00;
if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus
else if (twobytes == 0x8202)
{
highbyte = binr.ReadByte(); //advance 2 bytes
lowbyte = binr.ReadByte();
}
else
return null;
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; //reverse byte order since asn.1 key uses big endian order
int modsize = BitConverter.ToInt32(modint, 0);
int firstbyte = binr.PeekChar();
if (firstbyte == 0x00)
{ //if first byte (highest order) of modulus is zero, don't include it
binr.ReadByte(); //skip this null byte
modsize -= 1; //reduce modulus buffer size by 1
}
byte[] modulus = binr.ReadBytes(modsize); //read the modulus bytes
if (binr.ReadByte() != 0x02) //expect an Integer for the exponent data
return null;
int expbytes = (int)binr.ReadByte(); // should only need one byte for actual exponent data (for all useful values)
byte[] exponent = binr.ReadBytes(expbytes);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
var rsa = RSA.Create();
RSAParameters rsaKeyInfo = new RSAParameters
{
Modulus = modulus,
Exponent = exponent
};
rsa.ImportParameters(rsaKeyInfo);
return rsa;
}
}
}
#endregion
#region
private int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02)
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
count = binr.ReadByte();
else
if (bt == 0x82)
{
var highbyte = binr.ReadByte();
var lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt;
}
while (binr.ReadByte() == 0x00)
{
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current);
return count;
}
private 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;
}
#endregion
}
}

View File

@@ -0,0 +1,16 @@
using System;
namespace SDKCSharp.Utility
{
public enum SignType
{
/// <summary>
/// SHA1
/// </summary>
RSA = 0,
/// <summary>
/// RSA2 密钥长度至少为2048
/// SHA256
/// </summary>
RSA2
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace SDKCSharp.Utility
{
@@ -11,16 +12,45 @@ namespace SDKCSharp.Utility
{
/// <summary>
/// 构建签名
/// 构建签名
/// </summary>
/// <returns>The sign.</returns>
/// <param name="parameters">参数.</param>
/// <param name="privateKeyPem">私钥.</param>
/// <param name="privateKey">私钥.</param>
/// <param name="charset">字符集.</param>
/// <param name="signType">签名类型.</param>
/// <returns>返回签名.</returns>
public static string CreateSign(IDictionary<string, string> parameters, string privateKeyPem, string charset, bool isFromFile, string signType)
public static string CreateSign(IDictionary<string, string> parameters, string privateKey, Encoding charset, SignType signType)
{
return AlipaySignature.RSASign(parameters, privateKeyPem, charset, isFromFile, signType);
RSAHelper rsa = new RSAHelper(signType, charset, privateKey, null);
string content = GetSignContent(parameters);
return rsa.Sign(content);
}
/// <summary>
/// 构建签名内容
/// </summary>
/// <returns>The sign content.</returns>
/// <param name="parameters">Parameters.</param>
public static string GetSignContent(IDictionary<string, string> parameters)
{
// 第一步把字典按Key的字母顺序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder("");
while (dem.MoveNext())
{
string key = dem.Current.Key;
string value = dem.Current.Value;
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
{
query.Append(key).Append("=").Append(value).Append("&");
}
}
string content = query.ToString().Substring(0, query.Length - 1);
return content;
}
}