using System; using System.Security.Cryptography; using System.Text; using BWP.ABCClient.Common; namespace BWP.ABCClient { public static class RSAService { public static void Sign(MessageBase msgObj, string merchantID, Encoding msgEncoding, bool isMarket) { string xml = MsgUtil.MsgToBareXml(msgObj); var message = MsgUtil.GetInnerXml(xml, "Message"); message = isMarket ? string.Format("{0}", message) : message; msgObj.Signature = Sign(message, merchantID, msgEncoding); } public static string Sign(string msg, string merchantID) { return Sign(msg, merchantID, Encoding.Default); } public static string Sign(string msg, string merchantID, Encoding msgEncoding) { var cert = new CertManager().Fetch(merchantID); var privateKey = (RSACryptoServiceProvider)cert.PrivateKey; if (privateKey == null) { throw new Exception("商户的证书中没有私钥,请上传有效的证书"); } byte[] rgbHash = new SHA1Managed().ComputeHash(msgEncoding.GetBytes(msg)); byte[] data = privateKey.SignHash(rgbHash, cert.SignatureAlgorithm.Value); return Convert.ToBase64String(data); } public static bool Verify(string returnMsg, string abcSign) { return Verify(returnMsg, abcSign, Encoding.Default, false); } public static bool Verify(string returnMsg, string abcSign, Encoding msgEncoding, bool isTest) { var certMgr = new CertManager(); var cert = isTest ? certMgr.GetABCTestPubKey() : certMgr.GetABCPubKey(); var publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key; var singature = Convert.FromBase64String(abcSign); var msgHash = new SHA1Managed().ComputeHash(msgEncoding.GetBytes(returnMsg)); return publicKey.VerifyHash(msgHash, cert.SignatureAlgorithm.Value, singature); } public static bool Verify(string receivedXml, Encoding msgEncoding, bool isMarket, bool isTest) { string message = MsgUtil.GetInnerXml(receivedXml, "Message"); message = isMarket ? string.Format("{0}", message) : message; string signature = MsgUtil.GetInnerXml(receivedXml, "Signature"); return Verify(message, signature, msgEncoding, isTest); } public static bool TestVerify(string returnMsg, string abcSign) { return TestVerify(returnMsg, abcSign, Encoding.Default); } public static bool TestVerify(string returnMsg, string abcSign, Encoding msgEncoding) { var cert = new CertManager().GetABCTestPubKey(); var publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key; var singature = Convert.FromBase64String(abcSign); var msgHash = new SHA1Managed().ComputeHash(msgEncoding.GetBytes(returnMsg)); return publicKey.VerifyHash(msgHash, cert.SignatureAlgorithm.Value, singature); } } }