和建行的交互流程是:
-
首先建行会提供一个信息登记表,把表信息填写好,让建行做审批,审批完成后,会给一些电子合约编号。(注:提供的外网映射IP地址,一定要固定,不知道是否固定,需要问问相关的网络管理员,不然不固定,到时做telnet会不通的)
-
建行申请下来,并且telnet也通过后,可以和建行人员进行秘钥交互了。首先提供我们的SM2公钥地址,让建行下载使用。需要把我们对称的私钥保存好,以便做后续的加密验签操作。
-
银行下载安装好我们的SM2公钥之后,就可以下载银行的SM2公钥和SM4秘钥。也需要保存银行的SM2公钥和SM4秘钥。
-
每次做其它交易前需要做签到处理,如果你的交易是24小时进行的话,就没必要做签退了。但是必须要一天一签。
-
国密帮助类里面包含加密解密、生成建设银行需要的格式秘钥验签等方法,需要的请自行下载。
-
建行要求的报文为xml格式,但是拼接xml不美观且不容易维护,所以我就用实体来保存值,在通过xml序列化工具进行生成xml报文。
-
写的看不懂地方,请私信我,有时间就回复。
/// <summary>
/// 银行下载客户SM2秘钥
/// </summary>
/// <param name="type"></param>
/// <param name="chanl_cust_no"></param>
[HttpPost]
public void GetSM2PublicKey()
{
byte[] header = Encoding.UTF8.GetBytes("000000");
try
{
var Chanl_Cust_No = "YN00000000000000001";// 电子合约号,需要银行提供
// 获取银行需要的公钥
// 建行规定客户SM2公钥:000000+密钥密文, 000000 不需进行加密,密钥密文使用 SM4 加密后,以字节流返回。 其中 SM2 公钥的明文格式是椭圆曲线 Q 点不进行压缩时对应删除压缩标识位的二进制字节数组, 最后的字节数组的长度为 64
var bankTulp = GMHelper.GetCustKeyToBank();
var publicKey = bankTulp.Item1;
var privateKey = bankTulp.Item2;
// 获取SM4秘钥加密规则
var sm4SecretKey = GMHelper.GetSm4SecretKey(Chanl_Cust_No, DateTime.Now.ToString("yyMMdd"));
// 加密秘钥
var encryptedPubKey = GMHelper.Sm4EncryptECB(sm4SecretKey, publicKey, GMHelper.SM4_ECB_PKCS5Padding);
Response.BinaryWrite(header);
Response.BinaryWrite(encryptedPubKey);
Response.Flush();
Response.End();
return;
}
catch (Exception e)
{
header = Encoding.UTF8.GetBytes("000001");
var error = Encoding.UTF8.GetBytes(e.Message);
Response.BinaryWrite(header);
Response.BinaryWrite(error);
Response.Flush();
Response.End();
return;
}
}
/// <summary>
/// 银行秘钥交互
/// </summary>
/// <param name="type"></param>
/// <param name="chanl_cust_no"></param>
[HttpPost]
public string SecretKeyTransfer(string type, string chanl_cust_no)
{
var msg = string.Empty;
if (!string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(chanl_cust_no))
{
var param = new Domain.Supplier.DTO.CCBDirectParam();
param.ChanlCustNo = chanl_cust_no;
param.Type = type;
msg = Eps.Comm.Singleton.Instance.EpsWebServiceBLO.GetBankSM2OrSM4SecretKey(param);
}
return msg;
}
/// <summary>
/// 定时任务执行银行签到 每天签一次
/// </summary>
/// <param name="pkId"></param>
public void AutoBankSignIn_Tran(int pkId = 0)
{
try
{
var payfrom = Eps.Comm.Singleton.Instance.BasicDataServiceBLO.GetSysConfig("PayFromToOnline"); // 是否线上缴费;1线上;0线下
int.TryParse(payfrom, out int PayfromType);
if (PayfromType != 1)
{
return;
}
var secreKeys = GetBankSecreKeyInfoList();
var item = ValidateSecreKey(secreKeys);
if (!item.Item1)
{
WonderFramework.Common.BaseLogger.CustomWriteLog($"AutoBankSignIn_Tran{
DateTime.Now.ToString("yyyyMMdd")}.txt", item.Item2);
return;
}
var sm4Key = string.Empty;
var sm2Key = string.Empty;
var custPrivateKey = string.Empty;
if (secreKeys.Any(p => p.SecretKeyType == "sm4"))
{
sm4Key = secreKeys.Where(p => p.SecretKeyType == "sm4").FirstOrDefault().SecretKeyPublicKey;
}
if (secreKeys.Any(p => p.SecretKeyType == "sm2_pub"))
{
sm2Key = secreKeys.Where(p => p.SecretKeyType == "sm2_pub").FirstOrDefault().SecretKeyPublicKey;
}
if (secreKeys.Any(p => p.SecretKeyType