巴布鱼——软件工程师的家园

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 404|回复: 0

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

[复制链接]

35

主题

36

帖子

304

积分

中级会员

Rank: 3Rank: 3

积分
304
QQ
发表于 2018-1-4 15:47:09 | 显示全部楼层 |阅读模式
本帖最后由 笒羽 于 2018-1-8 16:17 编辑



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


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


经过一系列的的折腾,终于在C#下加密结果和微信对上,下面罗列步骤:
1、通过微信接口得到商户公钥文本,如:(以下内容仅为示例,不能直接拿来测试)
  1. -----BEGIN RSA PUBLIC KEY-----
  2. MIIBCgKCAQEAlQo5gP0vA0slDYO0h13AHiOzVvFEgdDYCUbBsCbe12zKFpE7qS7a
  3. 2UpfH8VVlhsFeOcuW1NhFCVe3MT51Z8JyTyJdAfhH3JvSp8suG/fz7CPipmpwL7L
  4. Hgk0hpKweQNxVEqp9Ol8ar/Z9TNJxim8Yb4I+NFIrSX5yj/4qhko8eC2byzQ4KwL
  5. n1j86vLVJH3U3NRa8VFnq3QR111TFN0HgZ4ZguMJaoGZMkFyhNawZqQGDu12Lh2/
  6. NrxV89eClb9HL8XloFyHabrXhM2uM0BAXMr5jEH8ukndbkbN/yl37JZZ/9oTvbMI
  7. uVS/2n5mrpmZlg+k8eO4l0I6uoOM8H0AcQIDAQAB
  8. -----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自行替换为您的本地文件
  1. c:\Openssl>openssl rsa -RSAPublicKey_in -in d:\public.pem -pubout
复制代码
得到转换后的文本内容
  1. -----BEGIN PUBLIC KEY-----
  2. MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlQo5gP0vA0slDYO0h13A
  3. HiOzVvFEgdDFSAbBsCbe12zKFpE7qS7a2UpfH8VVlhsFeOcuW1NhWKVe3MT51Z8J
  4. yTyJdAfhH3JvSp8suG/fz7CPipmpwL7LHgk0hpKweQNxVEqp9Ol8ar/Z9TNJxim8
  5. Yb4I+NFIrSX5yj/4qhko8eC2byzQ4KwLn1j86vLVJH3U3NRa8VFnq3QR227TFN0H
  6. gZ4ZguMJaoGZMkFyhNawZqEWDu12Lh2/NrxV89eClb9HL8XloFyHabrXhM2uM0BA
  7. XMr5jEH8ukndbkbN/yl37JZZ/9oTvbMIuVS/2n5mrpmZlg+k8eO4l0I6uoOM8H0A
  8. cQIDAQAB
  9. -----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、代码如下(方法自行编写):
  1. string keyfile="d:\\public_8.pem";//#8格式pem公钥文件
  2. string content = File.ReadAllText(keyfile, Encoding.ASCII);//获取pem证书完整内容
  3. if (string.IsNullOrEmpty(content))
  4. {
  5.     throw new ArgumentNullException("pemFileConent", "This arg cann't be empty.");
  6. }
  7. string publickeyConent = content.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");//去掉证书的头部和尾部
  8. RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicJavaKey));

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



文本,总结重点流程:调用微信获取商户公钥接口,得到公钥文本,保存为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






回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|巴布鱼

GMT+8, 2018-11-15 20:13 , Processed in 0.307018 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表