优化代码

This commit is contained in:
varorbc
2017-10-19 14:46:25 +08:00
parent bab5b07c54
commit 03365ba0cb
9 changed files with 261 additions and 219 deletions
@@ -1,8 +1,4 @@
using ICanPay.Alipay;
using ICanPay.Core;
using ICanPay.Tenpay;
using ICanPay.Wechatpay;
using ICanPay.Yeepay;
using ICanPay.Core;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
@@ -34,7 +30,7 @@ namespace ICanPay.Demo.Controllers
// 支付成功时时的处理代码
if (e.GatewayType == GatewayType.Alipay)
{
var alipayNotify = (Notify)e.Notify;
var alipayNotify = (Alipay.Notify)e.Notify;
}
}
@@ -82,7 +82,7 @@ namespace ICanPay.Demo.Controllers
};
var gateway = gatewayList.GetGateway(GatewayType.Alipay);
gateway.GatewayTradeType = GatewayTradeType.App;
gateway.GatewayTradeType = GatewayTradeType.Web;
PaymentSetting paymentSetting = new PaymentSetting(gateway, order);
return paymentSetting.Payment();
@@ -102,7 +102,7 @@ namespace ICanPay.Demo.Controllers
};
var gateway = gatewayList.GetGateway(GatewayType.Wechatpay);
gateway.GatewayTradeType = GatewayTradeType.Scan;
gateway.GatewayTradeType = GatewayTradeType.App;
PaymentSetting paymentSetting = new PaymentSetting(gateway, order);
return paymentSetting.Payment();
+4 -4
View File
@@ -143,8 +143,8 @@ namespace ICanPay.Alipay
GatewayData.Add(Constant.VERSION, Merchant.Version);
GatewayData.Add(Constant.NOTIFY_URL, Merchant.NotifyUrl);
GatewayData.Add(Constant.BIZ_CONTENT, Merchant.BizContent);
Merchant.Sign = Signature.RSASign(GatewayData.ToUrl(), Merchant.Privatekey, Merchant.Charset, Merchant.SignType, false);
GatewayData.Add(Constant.SIGN, Merchant.Sign); // 签名需要在最后设置,以免缺少参数。
Merchant.Sign = EncryptUtil.RSA2(GatewayData.ToUrl(), Merchant.Privatekey);
GatewayData.Add(Constant.SIGN, Merchant.Sign);
}
private string GetPaymentQueryString()
@@ -186,7 +186,7 @@ namespace ICanPay.Alipay
/// </summary>
private bool ValidateNotifySign()
{
Merchant.Sign = Signature.RSASign(GatewayData.ToUrl(Constant.SIGN, Constant.SIGN_TYPE), Merchant.Privatekey, Merchant.Charset, Merchant.SignType, false);
Merchant.Sign = EncryptUtil.RSA2(GatewayData.ToUrl(Constant.SIGN, Constant.SIGN_TYPE), Merchant.Privatekey);
// 验证通知的签名
if (string.Compare(Notify.Sign, Merchant.Sign) == 0)
{
@@ -202,7 +202,7 @@ namespace ICanPay.Alipay
private bool ValidateNotifyId()
{
// 服务器异步通知的通知Id则会在输出标志成功接收到通知的success字符串后失效。
if (string.Compare(Util.ReadPage(GetValidateNotifyUrl()), TRUE) == 0)
if (string.Compare(HttpUtil.ReadPage(GetValidateNotifyUrl()), TRUE) == 0)
{
return true;
}
+1 -1
View File
@@ -7,7 +7,7 @@
<Title>ICanPay.Alipay</Title>
<Authors>Varorbc</Authors>
<Description>支付宝支付</Description>
<Version>1.0.3</Version>
<Version>1.0.4</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
@@ -3,11 +3,70 @@ using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace ICanPay.Alipay
namespace ICanPay.Core
{
internal class Signature
/// <summary>
/// 加密工具类
/// </summary>
public class EncryptUtil
{
public static string RSASign(string data, string privateKeyPem, string charset, string signType, bool keyFromFile)
#region MD5加密
/// <summary>
/// MD5加密
/// </summary>
/// <param name="data">数据</param>
public static string MD5(string data)
{
return MD5(data, Encoding.UTF8);
}
/// <summary>
/// MD5加密
/// </summary>
/// <param name="data">数据</param>
/// <param name="encoding">编码</param>
/// <returns></returns>
public static string MD5(string data, Encoding encoding)
{
var md5 = System.Security.Cryptography.MD5.Create();
byte[] dataByte = md5.ComputeHash(encoding.GetBytes(data));
var sb = new StringBuilder();
for (int i = 0; i < dataByte.Length; i++)
{
sb.Append(dataByte[i].ToString("X2"));
}
return sb.ToString();
}
#endregion
#region RSA加密
/// <summary>
/// RSA加密
/// </summary>
/// <param name="data">数据</param>
/// <param name="privateKey">私钥</param>
/// <returns></returns>
public static string RSA(string data, string privateKey)
{
return RSA(data, privateKey, "UTF-8", "RSA", false);
}
/// <summary>
/// RSA2加密
/// </summary>
/// <param name="data">数据</param>
/// <param name="privateKey">私钥</param>
/// <returns></returns>
public static string RSA2(string data, string privateKey)
{
return RSA(data, privateKey, "UTF-8", "RSA2", false);
}
private static string RSA(string data, string privateKeyPem, string charset, string signType, bool keyFromFile)
{
byte[] signatureBytes = null;
@@ -15,7 +74,8 @@ namespace ICanPay.Alipay
{
RSACryptoServiceProvider rsaCsp = null;
if (keyFromFile)
{//文件读取
{
//文件读取
rsaCsp = LoadCertificateFile(privateKeyPem, signType);
}
else
@@ -25,6 +85,7 @@ namespace ICanPay.Alipay
}
byte[] dataBytes = null;
if (string.IsNullOrEmpty(charset))
{
dataBytes = Encoding.UTF8.GetBytes(data);
@@ -33,26 +94,26 @@ namespace ICanPay.Alipay
{
dataBytes = Encoding.GetEncoding(charset).GetBytes(data);
}
if (null == rsaCsp)
{
throw new Exception("您使用的私钥格式错误,请检查RSA私钥配置" + ",charset = " + charset);
}
if ("RSA2".Equals(signType))
{
signatureBytes = rsaCsp.SignData(dataBytes, "SHA256");
}
else
{
signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");
}
}
catch (Exception)
{
throw new Exception("您使用的私钥格式错误,请检查RSA私钥配置" + ",charset = " + charset);
}
return Convert.ToBase64String(signatureBytes);
}
@@ -69,8 +130,7 @@ namespace ICanPay.Alipay
}
try
{
RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(res, signType);
return rsa;
return DecodeRSAPrivateKey(res, signType);
}
catch (Exception)
{
@@ -81,19 +141,13 @@ namespace ICanPay.Alipay
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);
byte[] data = Convert.FromBase64String(strKey);
try
{
RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(data, signType);
return rsa;
return DecodeRSAPrivateKey(data, signType);
}
catch (Exception)
{
// throw new AopException("EncryptContent = woshihaoren,zheshiyigeceshi,wanerde", ex);
}
return null;
}
@@ -101,32 +155,39 @@ namespace ICanPay.Alipay
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
BinaryReader binr = new BinaryReader(mem);
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
if (twobytes == 0x8130)
{
binr.ReadByte();
}
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
{
binr.ReadInt16();
}
else
{
return null;
}
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
if (twobytes != 0x0102)
{
return null;
}
bt = binr.ReadByte();
if (bt != 0x00)
{
return null;
}
//------ all private key components are Integer sequences ----
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
@@ -151,10 +212,10 @@ namespace ICanPay.Alipay
elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
CspParameters CspParameters = new CspParameters();
CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
CspParameters CspParameters = new CspParameters
{
Flags = CspProviderFlags.UseMachineKeyStore
};
int bitLen = 1024;
if ("RSA2".Equals(signType))
@@ -163,15 +224,17 @@ namespace ICanPay.Alipay
}
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;
RSAParameters RSAparams = new RSAParameters
{
Modulus = MODULUS,
Exponent = E,
D = D,
P = P,
Q = Q,
DP = DP,
DQ = DQ,
InverseQ = IQ
};
RSA.ImportParameters(RSAparams);
return RSA;
}
@@ -204,31 +267,37 @@ namespace ICanPay.Alipay
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02) //expect integer
if (bt != 0x02)
{
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
count = binr.ReadByte();
}
else if (bt == 0x82)
{
highbyte = binr.ReadByte();
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt; // we already have the data size
count = bt;
}
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
binr.BaseStream.Seek(-1, SeekOrigin.Current);
return count;
}
#endregion
}
}
}
+121
View File
@@ -1,6 +1,8 @@
using Microsoft.AspNetCore.Http;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ICanPay
{
@@ -93,6 +95,125 @@ namespace ICanPay
Current.Response.WriteAsync(text).GetAwaiter().GetResult();
}
/// <summary>
/// 读取网页,返回网页内容
/// </summary>
/// <param name="pageUrl">网页URL</param>
/// <returns></returns>
public static string ReadPage(string pageUrl)
{
return ReadPage(pageUrl, Encoding.UTF8);
}
/// <summary>
/// 异步读取网页,返回网页内容
/// </summary>
/// <param name="pageUrl">网页URL</param>
/// <returns></returns>
public static async Task<string> ReadPageAsync(string pageUrl)
{
return await ReadPageAsync(pageUrl, Encoding.UTF8);
}
/// <summary>
/// 读取网页,返回网页内容
/// </summary>
/// <param name="pageUrl">网页URL</param>
/// <param name="pageEncoding">网页编码</param>
/// <returns></returns>
public static string ReadPage(string pageUrl, Encoding pageEncoding)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pageUrl);
request.Method = "GET";
try
{
using (WebResponse response = request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), pageEncoding))
{
if (reader != null)
{
return reader.ReadToEnd().Trim();
}
}
}
}
catch
{
}
finally
{
request.Abort();
}
return string.Empty;
}
/// <summary>
/// 读取网页,返回网页内容
/// </summary>
/// <param name="pageUrl">网页URL</param>
/// <param name="pageEncoding">网页编码</param>
/// <returns></returns>
public static async Task<string> ReadPageAsync(string pageUrl, Encoding pageEncoding)
{
return await Task.Run(() => ReadPage(pageUrl, pageEncoding));
}
/// <summary>
/// Post请求
/// </summary>
/// <param name="url">链接</param>
/// <param name="data">数据</param>
/// <returns></returns>
public static string Post(string url, string data)
{
byte[] dataByte = Encoding.UTF8.GetBytes(data);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentLength = dataByte.Length;
try
{
using (Stream outStream = request.GetRequestStream())
{
outStream.Write(dataByte, 0, dataByte.Length);
}
using (WebResponse response = request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
if (reader != null)
{
return reader.ReadToEnd().Trim();
}
}
}
}
catch
{
}
finally
{
request.Abort();
}
return string.Empty;
}
/// <summary>
/// 异步Post请求
/// </summary>
/// <param name="url">链接</param>
/// <param name="data">数据</param>
/// <returns></returns>
public static async Task<string> PostAsync(string url, string data)
{
return await Task.Run(() => Post(url, data));
}
#endregion
}
}
+11 -155
View File
@@ -1,170 +1,17 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace ICanPay.Core
{
/// <summary>
/// 支付的相关操作
/// 工具类
/// </summary>
public static class Util
{
#region 方法
/// <summary>
/// 获得字符串的MD5值,MD5值为大写
/// </summary>
/// <param name="text">字符串</param>
public static string GetMD5(string text)
{
return GetMD5(text, Encoding.UTF8);
}
/// <summary>
/// 获得字符串的MD5值,MD5值为大写
/// </summary>
/// <param name="text">字符串</param>
/// <param name="textEncoding">字符串编码</param>
/// <returns></returns>
public static string GetMD5(string text, Encoding textEncoding)
{
MD5 md5 = MD5.Create();
byte[] data = md5.ComputeHash(textEncoding.GetBytes(text));
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
stringBuilder.Append(data[i].ToString("X2"));
}
return stringBuilder.ToString();
}
/// <summary>
/// 读取网页,返回网页内容
/// </summary>
/// <param name="pageUrl">网页URL</param>
/// <returns></returns>
public static string ReadPage(string pageUrl)
{
return ReadPage(pageUrl, Encoding.UTF8);
}
/// <summary>
/// 异步读取网页,返回网页内容
/// </summary>
/// <param name="pageUrl">网页URL</param>
/// <returns></returns>
public static async Task<string> ReadPageAsync(string pageUrl)
{
return await ReadPageAsync(pageUrl, Encoding.UTF8);
}
/// <summary>
/// 读取网页,返回网页内容
/// </summary>
/// <param name="pageUrl">网页URL</param>
/// <param name="pageEncoding">网页编码</param>
/// <returns></returns>
public static string ReadPage(string pageUrl, Encoding pageEncoding)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pageUrl);
request.Method = "GET";
try
{
using (WebResponse response = request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), pageEncoding))
{
if (reader != null)
{
return reader.ReadToEnd().Trim();
}
}
}
}
catch
{
}
finally
{
request.Abort();
}
return string.Empty;
}
/// <summary>
/// 读取网页,返回网页内容
/// </summary>
/// <param name="pageUrl">网页URL</param>
/// <param name="pageEncoding">网页编码</param>
/// <returns></returns>
public static async Task<string> ReadPageAsync(string pageUrl, Encoding pageEncoding)
{
return await Task.Run(() => ReadPage(pageUrl, pageEncoding));
}
/// <summary>
/// Post请求
/// </summary>
/// <param name="url">链接</param>
/// <param name="data">数据</param>
/// <returns></returns>
public static string Post(string url, string data)
{
byte[] dataByte = Encoding.UTF8.GetBytes(data);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentLength = dataByte.Length;
try
{
using (Stream outStream = request.GetRequestStream())
{
outStream.Write(dataByte, 0, dataByte.Length);
}
using (WebResponse response = request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
if (reader != null)
{
return reader.ReadToEnd().Trim();
}
}
}
}
catch
{
}
finally
{
request.Abort();
}
return string.Empty;
}
/// <summary>
/// 异步Post请求
/// </summary>
/// <param name="url">链接</param>
/// <param name="data">数据</param>
/// <returns></returns>
public static async Task<string> PostAsync(string url, string data)
{
return await Task.Run(() => Post(url, data));
}
/// <summary>
/// 序列化对象
/// </summary>
@@ -195,7 +42,16 @@ namespace ICanPay.Core
return Guid.NewGuid().ToString().Replace("-", "");
}
#endregion
/// <summary>
/// 将时间转换为时间戳
/// </summary>
/// <param name="time">时间</param>
/// <returns></returns>
public static int ToTimeStamp(this DateTime time)
{
return (int)(time.ToUniversalTime().Ticks / 10000000 - 62135596800);
}
#endregion
}
}
+2 -2
View File
@@ -196,7 +196,7 @@ namespace ICanPay.Tenpay
/// <returns></returns>
private bool ValidateNotifyId()
{
string resultXml = Util.ReadPage(GetValidateNotifyUrl(), pageEncoding);
string resultXml = HttpUtil.ReadPage(GetValidateNotifyUrl(), pageEncoding);
// 需要先备份并清除之前接收到的网关的通知的数据,否者会对数据的验证造成干扰。
GatewayData gatewayData = BackupAndClearGatewayData();
ReadResultXml(resultXml);
@@ -294,7 +294,7 @@ namespace ICanPay.Tenpay
public bool QueryNow()
{
ReadResultXml(Util.ReadPage(GetQueryOrderUrl(), pageEncoding));
ReadResultXml(HttpUtil.ReadPage(GetQueryOrderUrl(), pageEncoding));
if (ValidateNotifyParameter() && ValidateOrder())
{
return true;
+1 -1
View File
@@ -196,7 +196,7 @@ namespace ICanPay.Yeepay
/// <returns></returns>
public bool QueryNow()
{
ReadQueryReturn(Util.ReadPage(GetQueryOrderUrl()));
ReadQueryReturn(HttpUtil.ReadPage(GetQueryOrderUrl()));
return ValidateQuery();
}