笒羽 发表于 2018-1-4 15:47:09

微信支付企业转帐到银行卡 RSA加密算法

本帖最后由 笒羽 于 2018-1-8 16:17 编辑



======本帖为原创贴,转载请注明出处,谢谢。QQ群:197599146,一个人的技术论坛,http://bbs.babuyu.com=========


微信支付企业转到到银行卡时,银行卡卡号和姓名需要进行RSA加密后提交到接口通过接口得到支付帐号的公钥,使用公钥加密如果算法错误,则接口就会返回:真实姓名或银行卡号出错


经过一系列的的折腾,终于在C#下加密结果和微信对上,下面罗列步骤:
1、通过微信接口得到商户公钥文本,如:(以下内容仅为示例,不能直接拿来测试)
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAlQo5gP0vA0slDYO0h13AHiOzVvFEgdDYCUbBsCbe12zKFpE7qS7a
2UpfH8VVlhsFeOcuW1NhFCVe3MT51Z8JyTyJdAfhH3JvSp8suG/fz7CPipmpwL7L
Hgk0hpKweQNxVEqp9Ol8ar/Z9TNJxim8Yb4I+NFIrSX5yj/4qhko8eC2byzQ4KwL
n1j86vLVJH3U3NRa8VFnq3QR111TFN0HgZ4ZguMJaoGZMkFyhNawZqQGDu12Lh2/
NrxV89eClb9HL8XloFyHabrXhM2uM0BAXMr5jEH8ukndbkbN/yl37JZZ/9oTvbMI
uVS/2n5mrpmZlg+k8eO4l0I6uoOM8H0AcQIDAQAB
-----END RSA PUBLIC KEY-----2、将接口返回的文本保存为pem文件,如:d:\public.pem,注意,文本所提到的保存文件均需以“UTF-8无BOM格式编码”保存,否则可能由于编码问题导致密文结果不一致,如何保存编码格式自行百度。。。。
3、将RSA公钥格式PKCS#1转为PKCS#8
A、下载openssl(本地末端有提供下载)
B、解压缩openssl-1.0.2j-fips-x86_64.zip到c:\openssl
C、执行转换命令(d:\public.pem自行替换为您的本地文件)
c:\Openssl>openssl rsa -RSAPublicKey_in -in d:\public.pem -pubout得到转换后的文本内容
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlQo5gP0vA0slDYO0h13A
HiOzVvFEgdDFSAbBsCbe12zKFpE7qS7a2UpfH8VVlhsFeOcuW1NhWKVe3MT51Z8J
yTyJdAfhH3JvSp8suG/fz7CPipmpwL7LHgk0hpKweQNxVEqp9Ol8ar/Z9TNJxim8
Yb4I+NFIrSX5yj/4qhko8eC2byzQ4KwLn1j86vLVJH3U3NRa8VFnq3QR227TFN0H
gZ4ZguMJaoGZMkFyhNawZqEWDu12Lh2/NrxV89eClb9HL8XloFyHabrXhM2uM0BA
XMr5jEH8ukndbkbN/yl37JZZ/9oTvbMIuVS/2n5mrpmZlg+k8eO4l0I6uoOM8H0A
cQIDAQAB
-----END PUBLIC KEY-----通过对比,#1与#8的格式描述是有区别的,#1为“RSA PUBLIC KEY”,#8为“PUBLIC KEY”
D、保存#8格式的文本内容为文件,如d:\public_8.pem
4、将pem转换为适用于C#的xml版密钥文件
A、下载BouncyCastle.Crypto.dll(本帖末端有提供下载),引用到C#项目
B、代码如下(方法自行编写):
string keyfile="d:\\public_8.pem";//#8格式pem公钥文件
string content = File.ReadAllText(keyfile, Encoding.ASCII);//获取pem证书完整内容
if (string.IsNullOrEmpty(content))
{
    throw new ArgumentNullException("pemFileConent", "This arg cann't be empty.");
}
string publickeyConent = content.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");//去掉证书的头部和尾部
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicJavaKey));

string xmlpublicKey = string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
//自行编写输出xmlpublicKey变量,内容即为转换后的XML版公钥输出内容如下:
<RSAKeyValue><Modulus>lQo5gP0vA0slDYO0h13AHiOzVvFEgdDYCUbBsCbe12zKFpE7qS7a2UpfH8VVlhsFeOcuW1NhFEVe3MT51Z8JyTyJdAfhH3JvSp8suG/fz7CPipmpwL7LHgk0hpKweQNxVEqp9Ol8ar/Z9TNJxim8Yb4I+NFIrSX5yj/4qhko8eC2byzQ4KwLn1j86vLVJH3U3NRa8VFnq3QR227TFN0HgZ4ZguMJaoGZMkFyhNawZqQGEE12Lh2/NrxV89eClb9HL8XloFyHabrXhM2uM0BAXMr5jEH8ukndbkbN/yl37JZZ/9oTvbMIuVS/2n5mrpmZlg+k8eO4l0I6uoOM8H0AcQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>5、使用XML版公钥加密文本,content参数为欲加密文本,方法如下:
public static string RSAEncrypt(string content)
      {
            string xml = "<RSAKeyValue><Modulus>lQo5gP0vA0slDYO0h13AHiOzVvFEgdDYCUbBsCbe12zKFpE7qS7a2UpfH8VVlhsFeOcuW1NhFEVe3MT51Z8JyTyJdAfhH3JvSp8suG/fz7CPipmpwL7LHgk0hpKweQNxVEqp9Ol8ar/Z9TNJxim8Yb4I+NFIrSX5yj/4qhko8eC2byzQ4KwLn1j86vLVJH3U3NRa8VFnq3QR227TFN0HgZ4ZguMJaoGZMkFyhNawZqQGEE12Lh2/NrxV89eClb9HL8XloFyHabrXhM2uM0BAXMr5jEH8ukndbkbN/yl37JZZ/9oTvbMIuVS/2n5mrpmZlg+k8eO4l0I6uoOM8H0AcQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            byte[] cipherbytes;
            rsa.FromXmlString(xml);
            cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), true);
            return Convert.ToBase64String(cipherbytes);
      }


文本,总结重点流程:调用微信获取商户公钥接口,得到公钥文本,保存为pem文件,使用openssl将默认#1格式转换#8格式pem文件,使用BouncyCastle组件将#8格式pem公钥文件转换为适用于C#的xml公钥文件。
如有问题欢迎加加入QQ群:197599146交流。

======本帖为原创贴,转载请注明出处,谢谢。QQ群:197599146,一个人的技术论坛,http://bbs.babuyu.com=========


附件下载地址:
链接: https://pan.baidu.com/s/1nvQkJxv 密码: 7r5h






页: [1]
查看完整版本: 微信支付企业转帐到银行卡 RSA加密算法