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("<Message>" + aMessage.ToString() + "</Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>" + str + "</Signature>");
|
|
}
|
|
|
|
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 = "<SignReq><Password>" + str3 + "</Password><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Data>" + str4 + "</Data></SignReq>\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 = "<Message>" + aMessage.ToString() + "</Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>" + str6 + "</Signature>";
|
|
} 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;
|
|
}
|
|
}
|
|
}
|
|
}
|