using com.hitrust.Security.Certificates; using System; using System.Collections; using System.IO; using System.Net; using System.Net.Sockets; using System.Security.Cryptography; using System.Text; using System.Security.Cryptography.X509Certificates; namespace com.hitrust.trustpay.client { public class MerchantConfig { private static readonly Hashtable iHashMerchantCertificates = new Hashtable(); private static readonly Hashtable iHashMerchantKeys = new Hashtable(); private static bool iIsInitialed = false; private static bool iIsLog = false; private static string iKeyStoreType = "0"; private static string iLogPath = ""; private static int iMerchantNum = 1; private static string iNewLine = "1"; private static IniFileParser iResourceBundle = null; private static readonly string iSHA1OID = CryptoConfig.MapNameToOID("SHA1"); private static X509Certificate iTrustpayCertificate = null; private static string iTrustPayConnectMethod = "http"; private static string iTrustPayServerName = ""; private static int iTrustPayServerPort = 0; private static string iTrustPayTrxURL = ""; public const string KEY_STORE_TYPE_FILE = "0"; public const string KEY_STORE_TYPE_SIGN_SERVER = "1"; private const string RESOURCE_NAME = @"C:\WINNT\system32\TrustMerchant.ini"; private const string SIGNATURE_ALGORITHM = "SHA1withRSA"; public MerchantConfig() { bundle(); } private static void bindMerchantCertificateByFile() { lock (typeof(MerchantConfig)) { string str = getParameterByName("MerchantID"); if (str.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 商户号[MerchantID]配置错误!"); } Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 商户编号 = [" + str + "]"); string str2 = getParameterByName("MerchantCertFile"); if (str2.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误", "商户证书储存目录档名[MerchantCertFile]配置错误!"); } string str3 = getParameterByName("MerchantCertPassword"); if (str2.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误", "商户私钥加密密码[MerchantCertPassword]配置错误!"); } char[] separator = new char[] {','}; string[] strArray = str.Split(separator, 100); iMerchantNum = strArray.Length; string[] strArray2 = str2.Split(separator, 100); string[] strArray3 = str3.Split(separator, 100); if ((iMerchantNum != strArray2.Length) || (iMerchantNum != strArray3.Length)) { throw new TrxException("1007", "配置文件中MerchantID、MerchantCertFile、MerchantCertPassword属性个数不一致", ""); } iHashMerchantCertificates.Clear(); iHashMerchantKeys.Clear(); for (int i = 0; i < iMerchantNum; i++) { Certificate certificate = null; if (!File.Exists(strArray2[i])) { Console.WriteLine("File does not exist: " + strArray2[i]); } if (strArray3[i] != null) { try { certificate = Certificate.CreateFromPfxFile(strArray2[i], strArray3[i], true, KeysetLocation.LocalMachine); } catch (Exception exception) { throw new TrxException("1002", "无法读取证书文档", "[" + strArray2[i] + "]!" + exception.Message); } } DateTime now = DateTime.Now; if (certificate.GetExpirationDate() < now) { throw new TrxException("1005", "证书过期"); } iHashMerchantCertificates.Add(strArray[i], certificate); try { iHashMerchantKeys.Add(strArray[i], certificate.PrivateKey); } catch (Exception exception2) { throw new TrxException("1003", "无法读取商户私钥", "无法生成私钥证书对象!" + exception2.Message); } } } } private static void bundle() { if (!iIsInitialed) { Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 开始===================="); try { string environmentVariable = Environment.GetEnvironmentVariable("TrustMerchantIniFile"); if (environmentVariable == null) { environmentVariable = @"C:\WINNT\system32\TrustMerchant.ini"; } iResourceBundle = new IniFileParser(environmentVariable); } catch (Exception) { Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 无法读取商户端配置文件"); throw new TrxException("1000", "无法读取商户端配置文件"); } Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 读取系统配置文件"); iTrustPayConnectMethod = getParameterByName("TrustPayConnectMethod"); if (iTrustPayConnectMethod.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 网上支付平台通讯方式[TrustPayConnectMethod]配置错误!"); } Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 网上支付平台通讯方式 = [" + iTrustPayConnectMethod + "]"); iTrustPayServerName = getParameterByName("TrustPayServerName"); if (iTrustPayServerName.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 网上支付平台服务器IP[TrustPayServerName]配置错误!"); } Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 网上支付平台服务器IP = [" + iTrustPayServerName + "]"); string s = getParameterByName("TrustPayServerPort"); if (s.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 网上支付平台交易端口[TrustPayServerPort]配置错误!"); } try { iTrustPayServerPort = int.Parse(s); } catch (Exception) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 网上支付平台交易端口[TrustPayServerPort]配置错误!"); } Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 网上支付平台交易端口 = [" + s + "]"); iTrustPayTrxURL = getParameterByName("TrustPayTrxURL"); if (iTrustPayTrxURL.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 网上支付平台交易网址[TrustPayTrxURL]配置错误!"); } Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 网上支付平台交易网址 = [" + iTrustPayTrxURL + "]"); string str3 = getParameterByName("TrustPayNewLine"); if (str3.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 网上支付平台接口特性[TrustPayNewLine]配置错误!"); } if (str3.Equals("1")) { iNewLine = "\n"; } else { iNewLine = "\r\n"; } Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 网上支付平台接口特性 = [" + str3 + "]"); string tCertFile = getParameterByName("TrustPayCertFile"); if (tCertFile.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 网上支付平台证书[tTrustPayCertFile]配置错误!"); } iTrustpayCertificate = getCertificate(tCertFile); Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 网上支付平台证书 = [" + tCertFile + "]"); string str5 = getParameterByName("EnableLog", false); if ((str5 != null) && str5.ToUpper().Equals("TRUE")) { iIsLog = true; } if (iIsLog) { iLogPath = getParameterByName("LogPath"); if (iLogPath.Length == 0) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 商户日志目录[LogPath]配置错误!"); } Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 日志文件目录 = [" + iLogPath + "]"); } iKeyStoreType = getParameterByName("MerchantKeyStoreType"); if (iKeyStoreType.Equals("0")) { bindMerchantCertificateByFile(); } else if (!iKeyStoreType.Equals("1")) { throw new TrxException("1001", "商户端配置文件中参数设置错误 - 证书储存媒体配置错误!"); } Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 商户证书及私钥初始完成"); iIsInitialed = true; Console.Out.WriteLine("[Trustpay商户端API] - 初始 - 完成===================="); } } private static XMLDocument fileSignMessage(string aMerchantNo, XMLDocument aMessage) { RSACryptoServiceProvider provider = MerchantKey(aMerchantNo); byte[] rgbHash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(aMessage.ToString())); byte[] data = provider.SignHash(rgbHash, iSHA1OID); string str = new Base64().encode(data); return new XMLDocument("" + aMessage.ToString() + "SHA1withRSA" + str + ""); } public static string FirstMerchantID() { bundle(); IDictionaryEnumerator enumerator = iHashMerchantCertificates.GetEnumerator(); if ((enumerator != null) && enumerator.MoveNext()) { return (string)enumerator.Key; } return null; } private static X509Certificate getCertificate(string tCertFile) { X509Certificate certificate = null; try { certificate = X509Certificate.CreateFromCertFile(tCertFile); } catch (Exception) { throw new TrxException("1002", "无法读取证书文档[" + tCertFile + "]!"); } return certificate; } public static string getParameterByName(string aParamName) { return getParameterByName(aParamName, true); } public static string getParameterByName(string aParamName, bool aThrowException) { if (iResourceBundle == null) { bundle(); } string str = null; try { str = iResourceBundle.getValue(aParamName).Trim(); if (str.Equals("") & aThrowException) { throw new TrxException("1001", "商户端配置文件中参数设置错误", " - 未设定[" + aParamName + "]参数值!"); } } catch (Exception) { if (aThrowException) { throw new TrxException("1001", "商户端配置文件中参数设置错误", " - 无[" + aParamName + "]参数!"); } } return str; } public static BufferedStream getTrxLogFile() { return getTrxLogFile("TrxLog"); } public static BufferedStream getTrxLogFile(string aFileName) { bundle(); BufferedStream stream = null; if (iIsLog) { string path = ""; try { HiCalendar calendar = new HiCalendar(); path = iLogPath + "/" + aFileName + "." + calendar.toString("%Y%m%d.log"); stream = new BufferedStream(new FileStream(path, FileMode.Append)); } catch (IOException) { throw new TrxException("1004", "无法写入交易日志文档", " - 系统无法写入交易日志至[" + path + "]中!"); } } return stream; } public static bool hasMerchant(string aMerchantNo) { bundle(); return iHashMerchantKeys.ContainsKey(aMerchantNo); } public static Certificate MerchantCertificate(string aMerchantNo) { bundle(); IDictionaryEnumerator enumerator = iHashMerchantCertificates.GetEnumerator(); if (enumerator != null) { while (enumerator.MoveNext()) { if (enumerator.Key.Equals(aMerchantNo)) { return (Certificate)enumerator.Value; } } return null; } return null; } public static string MerchantID(string aMerchantNo) { bundle(); return aMerchantNo; } public static RSACryptoServiceProvider MerchantKey(string aMerchantNo) { bundle(); IDictionaryEnumerator enumerator = iHashMerchantKeys.GetEnumerator(); if (enumerator != null) { while (enumerator.MoveNext()) { if (enumerator.Key.Equals(aMerchantNo)) { return (RSACryptoServiceProvider)enumerator.Value; } } return null; } return null; } public static XMLDocument signMessage(string aMerchantNo, XMLDocument aMessage) { bundle(); XMLDocument document = null; try { string keyStoreType = KeyStoreType; if (keyStoreType.Equals("0")) { return fileSignMessage(aMerchantNo, aMessage); } if (keyStoreType.Equals("1")) { document = signServerSignMessage(aMessage); } } catch (TrxException exception) { throw exception; } catch (Exception exception2) { throw new TrxException("1102", "签名交易报文时发生错误 - " + exception2.Message); } return document; } private static XMLDocument signServerSignMessage(XMLDocument aMessage) { string aXMLString = ""; Socket socket = null; string hostName = getParameterByName("SignServerIP"); int port = int.Parse(getParameterByName("SignServerPort")); string str3 = getParameterByName("SignServerPassword"); try { IPEndPoint remoteEP = new IPEndPoint(Dns.GetHostEntry(hostName).AddressList[0], port); socket = new Socket(remoteEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 0x2710); socket.Connect(remoteEP); string str4 = new Base64().encode(Encoding.UTF8.GetBytes(aMessage.ToString())); string s = "" + str3 + "SHA1withRSA" + str4 + "\n"; socket.Send(Encoding.ASCII.GetBytes(s)); byte[] buffer = new byte[0x800]; int count = socket.Receive(buffer); XMLDocument document = new XMLDocument(Encoding.ASCII.GetString(buffer, 0, count)); string str6 = ""; if (!document.getValueNoNull("RC").Equals("0")) { throw new TrxException("1104", "签名服务器返回签名错误", "错误代码[" + document.getValueNoNull("RC") + "]"); } str6 = document.getValueNoNull("Signature"); aXMLString = "" + aMessage.ToString() + "SHA1withRSA" + str6 + ""; } catch (TrxException exception) { throw exception; } catch (Exception exception2) { throw new TrxException("1103", "无法连线签名服务器", exception2.StackTrace); } finally { if (socket != null) { socket.Close(); } } return new XMLDocument(aXMLString); } public static XMLDocument verifySign(XMLDocument aMessage) { bundle(); XMLDocument document = aMessage.getValue("Message"); if (document == null) { throw new TrxException("1301", "网上支付平台的响应报文不完整", "无[Message]段!"); } if (aMessage.getValueNoNull("Signature-Algorithm") == null) { throw new TrxException("1301", "网上支付平台的响应报文不完整", "无[Signature-Algorithm]段!"); } string data = aMessage.getValueNoNull("Signature"); if (data == null) { throw new TrxException("1301", "网上支付平台的响应报文不完整", "无[Signature]段!"); } byte[] rgbSignature = new Base64().decode(data); try { SHA1Managed managed = new SHA1Managed(); byte[] rgbHash = managed.ComputeHash(Encoding.GetEncoding("gb2312").GetBytes(document.ToString())); RSACryptoServiceProvider provider = new RSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore }); RSAParameters parameters = new RSAParameters() { Exponent = TrustpayCertificate.GetPublicKey() }; provider.ImportParameters(parameters); bool flag = provider.VerifyHash(rgbHash, iSHA1OID, rgbSignature); managed.Clear(); provider.Clear(); if (!flag) { throw new TrxException("1302", "网上支付平台的响应报文签名验证失败"); } } catch (TrxException exception) { throw exception; } catch (Exception exception2) { Console.Out.WriteLine(exception2); throw new TrxException("1302", "网上支付平台的响应报文签名验证失败 - " + exception2.Message); } return document; } public static string KeyStoreType { get { bundle(); return iKeyStoreType; } } public static int MerchantNum { get { bundle(); return iMerchantNum; } } public static X509Certificate TrustpayCertificate { get { bundle(); return iTrustpayCertificate; } } public static string TrustPayConnectMethod { get { bundle(); return iTrustPayConnectMethod; } } public static string TrustPayNewLine { get { bundle(); return iNewLine; } } public static string TrustPayServerName { get { bundle(); return iTrustPayServerName; } } public static int TrustPayServerPort { get { bundle(); return iTrustPayServerPort; } } public static string TrustPayTrxURL { get { bundle(); return iTrustPayTrxURL; } } } }