class Sign_verifySign
{
#region prepare string to sign.
//example format: a=123&b=xxx&c (with sort)
private static string encrypt<T>(T body)
{
var mType = body.GetType();
var props = mType.GetProperties().OrderBy(x => x.Name).ToArray();
StringBuilder sb = new StringBuilder();
foreach (var p in props)
{
if (p.Name != "sign" && p.Name != "signType" && p.GetValue(body, null) != null && p.GetValue(body, null).ToString() != "")
{
sb.Append(string.Format("{0}={1}&", p.Name, p.GetValue(body, null)));
}
}
var tmp = sb.ToString();
return tmp.Substring(, tmp.Length - );
}
#endregion #region sign
public static string sign(string content, string privateKey, string input_charset)
{
byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content);
RSACryptoServiceProvider rsa = DecodePemPrivateKey(privateKey);
SHA1 sh = new SHA1CryptoServiceProvider();
byte[] signData = rsa.SignData(Data, sh);
//get base64string -> ASCII byte[]
var base64ToByte = Encoding.ASCII.GetBytes(Convert.ToBase64String(signData));
string signresult = BitConverter.ToString(base64ToByte).Replace("-", string.Empty);
return signresult;
}
private static RSACryptoServiceProvider DecodePemPrivateKey(String pemstr)
{
byte[] pkcs8privatekey; pkcs8privatekey = Convert.FromBase64String(pemstr);
if (pkcs8privatekey != null)
{
RSACryptoServiceProvider rsa = DecodePrivateKeyInfo(pkcs8privatekey);
return rsa;
}
else return null;
}
private static RSACryptoServiceProvider DecodePrivateKeyInfo(byte[] pkcs8)
{
byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
byte[] seq = new byte[]; MemoryStream mem = new MemoryStream(pkcs8);
int lenstream = (int)mem.Length; BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = ;
ushort twobytes = ;
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(); //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 = DecodeRSAPrivateKey(rsaprivkey);
return rsacsp;
}
catch (Exception)
{return null;
}
finally
{
binr.Close();
}
}
private static bool CompareBytearrays(byte[] a, byte[] b)
{
if (a.Length != b.Length) return false;
int i = ; foreach (byte c in a)
{ if (c != b[i]) return false; i++; }
return true;
}
private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
{
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 = ;
ushort twobytes = ;
int elems = ;
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 -----
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
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 e)
{
return null;
}
finally { binr.Close(); }
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = ;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = ;
bt = binr.ReadByte();
if (bt != 0x02) //expect integer
return ;
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, );
}
else
{
count = bt; // we already have the data size
}while (binr.ReadByte() == 0x00)
{ //remove high order zeros in data
count -= ;
}
binr.BaseStream.Seek(-, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte
return count;
} #endregion #region verifySign
//onepay verify
public static bool verifyFromHexAscii(string sign, string publicKey, string content, string charset)
{
string decSign = System.Text.Encoding.UTF8.GetString(fromHexAscii(sign));
return verify(content, decSign, publicKey, charset);
}
public static byte[] fromHexAscii(string s)
{
try
{
int len = s.Length;
if ((len % ) != )
throw new Exception("Hex ascii must be exactly two digits per byte."); int out_len = len / ;
byte[] out1 = new byte[out_len];
int i = ;
StringReader sr = new StringReader(s);
while (i < out_len)
{
int val = ( * fromHexDigit(sr.Read())) + fromHexDigit(sr.Read());
out1[i++] = (byte)val;
}
return out1;
}
catch (IOException e)
{
throw new Exception("IOException reading from StringReader?!?!");
}
}
private static int fromHexDigit(int c)
{
if (c >= 0x30 && c < 0x3A)
return c - 0x30;
else if (c >= 0x41 && c < 0x47)
return c - 0x37;
else if (c >= 0x61 && c < 0x67)
return c - 0x57;
else
throw new Exception('\'' + c + "' is not a valid hexadecimal digit.");
} public static bool verify(string content, string signedString, string publicKey, string input_charset)
{
signedString = signedString.Replace("*", "+");
signedString = signedString.Replace("-", "/");
return JiJianverify(content, signedString, publicKey, input_charset); }
public static bool JiJianverify(string content, string signedString, string publicKey, string input_charset)
{
bool result = false;
byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content); byte[] data = Convert.FromBase64String(signedString);
RSAParameters paraPub = ConvertFromPublicKey(publicKey);
RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider();
rsaPub.ImportParameters(paraPub);
SHA1 sh = new SHA1CryptoServiceProvider();
result = rsaPub.VerifyData(Data, sh, data);
return result;
}
private static RSAParameters ConvertFromPublicKey(string pemFileConent)
{ byte[] keyData = Convert.FromBase64String(pemFileConent);
if (keyData.Length < )
{
throw new ArgumentException("pem file content is incorrect.");
}
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(keyData); RSAParameters para = new RSAParameters();
para.Modulus = publicKeyParam.Modulus.ToByteArrayUnsigned();
para.Exponent = publicKeyParam.Exponent.ToByteArrayUnsigned();
return para;
}
#endregion
}

最新文章

  1. C# 获取时间差状态
  2. java 接口中模拟浏览器 请求webservice 接受返回数据
  3. 当kfreebsd 用户遇见openSUSE系统
  4. 安装性能测试工具:sysbench和使用apache的ab
  5. [MySQL] 按日期进行统计(前一天、本周、某一天)
  6. JavaWeb基础:Servlet
  7. 赵雅智_Fragment生命周期
  8. The Time in Words
  9. 移动端h5页面的设计稿尺寸
  10. AFNetworking2.0和AFNetworking3.0 的HTTPS的配置
  11. hdu4417 Super Mario
  12. 复习HTML+CSS(4)
  13. 用Margin还是用Padding?(转载)
  14. Bigger-Mai 养成计划,Python基础巩固四
  15. go websocket
  16. python nose测试框架全面介绍十一---用例的发现
  17. SCU 4437 Carries(二分乱搞)题解
  18. git解决not a git repository
  19. C/C++之extern &quot;C&quot;的用法解析
  20. ecipse theme

热门文章

  1. SVN 分支主干的相互合并
  2. [每天解决一问题系列 - 0005] WiX Burn 如何校验chained package的合法性
  3. Ubuntu16.04 安装 wps (不推荐安装)
  4. Tensflow的equal函数
  5. mysql 开发进阶篇系列 41 mysql日志之慢查询日志
  6. 记录前台页面一些jQuery笔记
  7. Mysql常用单词
  8. [Cerc2012]Non-boring sequences
  9. CentOS6.5安装mysql以及常见问题的解决
  10. ELK日志分析平台系统windows环境搭建和基本使用