暂时没有看到关于微信支付APIv3 of C# 的SDK,对于新进来的开发人员在实现底层(签名,加密,验签)多多少少会碰一点点壁; 下面提供相关方法供参考。

文档中心:微信支付开发文档/开放平台 (建议看下开发指引等内容)

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;namespace TenpayV3.Utilities
{/// <summary>/// RSA 算法工具类。/// </summary>public static class RSAUtility{private const string RSA_CIPHER_ALGORITHM_ECB = "RSA/ECB";private const string RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1 = "OAEPWITHSHA1ANDMGF1PADDING";private const string RSA_SIGNER_ALGORITHM_SHA256 = "SHA-256withRSA";private static byte[] ConvertPrivateKeyPkcs8PemToByteArray(string privateKey){privateKey = privateKey.Replace("-----BEGIN PRIVATE KEY-----", string.Empty).Replace("-----END PRIVATE KEY-----", string.Empty);privateKey = Regex.Replace(privateKey, "\\s+", string.Empty);return Convert.FromBase64String(privateKey);}private static byte[] ConvertPublicKeyPkcs8PemToByteArray(string publicKey){publicKey = publicKey.Replace("-----BEGIN PUBLIC KEY-----", string.Empty).Replace("-----END PUBLIC KEY-----", string.Empty);publicKey = Regex.Replace(publicKey, "\\s+", string.Empty);return Convert.FromBase64String(publicKey);}private static X509Certificate ParseCertificatePemToX509(string certificate){using (TextReader sreader = new StringReader(certificate)){PemReader pemReader = new PemReader(sreader);return (X509Certificate)pemReader.ReadObject();}}private static RsaKeyParameters ParsePrivateKeyPemToPrivateKeyParameters(byte[] privateKeyBytes){return (RsaKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes);}private static RsaKeyParameters ParsePublicKeyPemToPublicKeyParameters(byte[] publicKeyBytes){return (RsaKeyParameters)PublicKeyFactory.CreateKey(publicKeyBytes);}private static byte[] SignWithSHA256(RsaKeyParameters rsaPrivateKeyParams, byte[] msgBytes){ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256);signer.Init(true, rsaPrivateKeyParams);signer.BlockUpdate(msgBytes, 0, msgBytes.Length);return signer.GenerateSignature();}private static bool VerifyWithSHA256(RsaKeyParameters rsaPublicKeyParams, byte[] msgBytes, byte[] signBytes){ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256);signer.Init(false, rsaPublicKeyParams);signer.BlockUpdate(msgBytes, 0, msgBytes.Length);return signer.VerifySignature(signBytes);}private static byte[] DecryptWithECB(RsaKeyParameters rsaPrivateKeyParams, byte[] cipherBytes, string paddingMode){IBufferedCipher cipher = CipherUtilities.GetCipher("{RSA_CIPHER_ALGORITHM_ECB}/{paddingMode}");cipher.Init(false, rsaPrivateKeyParams);return cipher.DoFinal(cipherBytes);}private static byte[] EncryptWithECB(RsaKeyParameters rsaPublicKeyParams, byte[] plainBytes, string paddingMode){IBufferedCipher cipher = CipherUtilities.GetCipher("{RSA_CIPHER_ALGORITHM_ECB}/{paddingMode}");cipher.Init(true, rsaPublicKeyParams);return cipher.DoFinal(plainBytes);}/// <summary>/// 使用私钥基于 SHA-256 算法生成签名。/// </summary>/// <param name="privateKeyBytes">PKCS#8 私钥字节数组。</param>/// <param name="msgBytes">待签名的数据字节数组。</param>/// <returns>签名字节数组。</returns>public static byte[] SignWithSHA256(byte[] privateKeyBytes, byte[] msgBytes){if (privateKeyBytes == null) throw new ArgumentNullException(nameof(privateKeyBytes));if (msgBytes == null) throw new ArgumentNullException(nameof(msgBytes));RsaKeyParameters rsaPrivateKeyParams = ParsePrivateKeyPemToPrivateKeyParameters(privateKeyBytes);return SignWithSHA256(rsaPrivateKeyParams, msgBytes);}/// <summary>/// 使用私钥基于 SHA-256 算法生成签名。/// </summary>/// <param name="privateKey">PKCS#8 私钥(PEM 格式)。</param>/// <param name="message">待签名的文本数据。</param>/// <returns>经 Base64 编码的签名。</returns>public static string SignWithSHA256(string privateKey, string message){if (privateKey == null) throw new ArgumentNullException(nameof(privateKey));if (message == null) throw new ArgumentNullException(nameof(message));byte[] privateKeyBytes = ConvertPrivateKeyPkcs8PemToByteArray(privateKey);byte[] msgBytes = Encoding.UTF8.GetBytes(message);byte[] signBytes = SignWithSHA256(privateKeyBytes, msgBytes);return Convert.ToBase64String(signBytes);}/// <summary>/// 使用公钥基于 SHA-256 算法验证签名。/// </summary>/// <param name="publicKeyBytes">PKCS#8 公钥字节数据。</param>/// <param name="msgBytes">待验证的数据字节数据。</param>/// <param name="signBytes">待验证的签名字节数据。</param>/// <returns>验证结果。</returns>public static bool VerifyWithSHA256(byte[] publicKeyBytes, byte[] msgBytes, byte[] signBytes){if (publicKeyBytes == null) throw new ArgumentNullException(nameof(publicKeyBytes));if (msgBytes == null) throw new ArgumentNullException(nameof(msgBytes));if (signBytes == null) throw new ArgumentNullException(nameof(signBytes));RsaKeyParameters rsaPublicKeyParams = ParsePublicKeyPemToPublicKeyParameters(publicKeyBytes);return VerifyWithSHA256(rsaPublicKeyParams, msgBytes, signBytes);}/// <summary>/// 使用公钥基于 SHA-256 算法验证签名。/// </summary>/// <param name="publicKey">PKCS#8 公钥(PEM 格式)。</param>/// <param name="message">待验证的文本数据。</param>/// <param name="signature">经 Base64 编码的待验证的签名。</param>/// <returns>验证结果。</returns>public static bool VerifyWithSHA256(string publicKey, string message, string signature){if (publicKey == null) throw new ArgumentNullException(nameof(publicKey));if (message == null) throw new ArgumentNullException(nameof(message));if (signature == null) throw new ArgumentNullException(nameof(signature));byte[] publicKeyBytes = ConvertPublicKeyPkcs8PemToByteArray(publicKey);byte[] msgBytes = Encoding.UTF8.GetBytes(message);byte[] signBytes = Convert.FromBase64String(signature);return VerifyWithSHA256(publicKeyBytes, msgBytes, signBytes);}/// <summary>/// 使用证书基于 SHA-256 算法验证签名。/// </summary>/// <param name="certificate">证书(PEM 格式)。</param>/// <param name="message">待验证的文本数据。</param>/// <param name="signature">经 Base64 编码的待验证的签名。</param>/// <returns>验证结果。</returns>public static bool VerifyWithSHA256ByCertificate(string certificate, string message, string signature){if (certificate == null) throw new ArgumentNullException(nameof(certificate));string publicKey = ExportPublicKeyFromCertificate(certificate);return VerifyWithSHA256(publicKey, message, signature);}/// <summary>/// 使用私钥基于 ECB 模式解密数据。/// </summary>/// <param name="privateKeyBytes">PKCS#8 私钥字节数据。</param>/// <param name="cipherBytes">待解密的数据字节数据。</param>/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/>)</param>/// <returns>解密后的数据字节数组。</returns>public static byte[] DecryptWithECB(byte[] privateKeyBytes, byte[] cipherBytes, string paddingMode){if (privateKeyBytes == null) throw new ArgumentNullException(nameof(privateKeyBytes));if (cipherBytes == null) throw new ArgumentNullException(nameof(cipherBytes));RsaKeyParameters rsaPrivateKeyParams = ParsePrivateKeyPemToPrivateKeyParameters(privateKeyBytes);return DecryptWithECB(rsaPrivateKeyParams, cipherBytes, paddingMode);}/// <summary>/// 使用私钥基于 ECB 模式解密数据。/// </summary>/// <param name="privateKey">PKCS#8 私钥(PEM 格式)。</param>/// <param name="cipherText">经 Base64 编码的待解密数据。</param>/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/>)</param>/// <returns>解密后的文本数据。</returns>public static string DecryptWithECB(string privateKey, string cipherText, string paddingMode){if (privateKey == null) throw new ArgumentNullException(nameof(privateKey));if (cipherText == null) throw new ArgumentNullException(nameof(cipherText));byte[] privateKeyBytes = ConvertPrivateKeyPkcs8PemToByteArray(privateKey);byte[] cipherBytes = Convert.FromBase64String(cipherText);byte[] plainBytes = DecryptWithECB(privateKeyBytes, cipherBytes, paddingMode);return Encoding.UTF8.GetString(plainBytes);}/// <summary>/// 使用公钥基于 ECB 模式加密数据。/// </summary>/// <param name="publicKeyBytes">PKCS#8 公钥字节数据。</param>/// <param name="plainBytes">待加密的数据字节数据。</param>/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/>)</param>/// <returns>加密后的数据字节数组。</returns>public static byte[] EncryptWithECB(byte[] publicKeyBytes, byte[] plainBytes, string paddingMode){if (publicKeyBytes == null) throw new ArgumentNullException(nameof(publicKeyBytes));if (plainBytes == null) throw new ArgumentNullException(nameof(plainBytes));RsaKeyParameters rsaPublicKeyParams = ParsePublicKeyPemToPublicKeyParameters(publicKeyBytes);return EncryptWithECB(rsaPublicKeyParams, plainBytes, paddingMode);}/// <summary>/// 使用公钥基于 ECB 模式加密数据。/// </summary>/// <param name="publicKey">PKCS#8 公钥(PEM 格式)。</param>/// <param name="plainText">待加密的文本数据。</param>/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/>)</param>/// <returns>经 Base64 编码的加密数据。</returns>public static string EncryptWithECB(string publicKey, string plainText, string paddingMode){if (publicKey == null) throw new ArgumentNullException(nameof(publicKey));if (plainText == null) throw new ArgumentNullException(nameof(plainText));byte[] publicKeyBytes = ConvertPublicKeyPkcs8PemToByteArray(publicKey);byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);byte[] cipherBytes = EncryptWithECB(publicKeyBytes, plainBytes, paddingMode);return Convert.ToBase64String(cipherBytes);}/// <summary>/// 使用证书基于 ECB 模式加密数据。/// </summary>/// <param name="certificate">证书(PEM 格式)。</param>/// <param name="plainText">待加密的文本数据。</param>/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/>)</param>/// <returns>经 Base64 编码的加密数据。</returns>public static string EncryptWithECBByCertificate(string certificate, string plainText, string paddingMode){if (certificate == null) throw new ArgumentNullException(nameof(certificate));string publicKey = ExportPublicKeyFromCertificate(certificate);return EncryptWithECB(publicKey, plainText, paddingMode);}/// <summary>/// <para>从 CRT/CER 证书中导出 PKCS#8 公钥。</para>/// <para>///     即从 -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----///     转为 -----BEGIN PUBLIC KEY----- ..... -----END PUBLIC KEY-----/// </para>/// </summary>/// <param name="certificate">证书(PEM 格式)。</param>/// <returns>PKCS#8 公钥(PEM 格式)。</returns>public static string ExportPublicKeyFromCertificate(string certificate){if (certificate == null) throw new ArgumentNullException(nameof(certificate));using (TextWriter swriter = new StringWriter()){X509Certificate x509cert = ParseCertificatePemToX509(certificate);RsaKeyParameters rsaPublicKeyParams = (RsaKeyParameters)x509cert.GetPublicKey();PemWriter pemWriter = new PemWriter(swriter);pemWriter.WriteObject(rsaPublicKeyParams);pemWriter.Writer.Flush();return swriter.ToString()!;}}/// <summary>/// <para>从 CRT/CER 证书中导出证书序列号。</para>/// </summary>/// <param name="certificate">证书(PEM 格式)。</param>/// <returns>证书序列号。</returns>public static string ExportSerialNumberFromCertificate(string certificate){if (certificate == null) throw new ArgumentNullException(nameof(certificate));X509Certificate x509cert = ParseCertificatePemToX509(certificate);return x509cert.SerialNumber.ToString(16);}/// <summary>/// <para>从 CRT/CER 证书中导出证书颁发时间。</para>/// </summary>/// <param name="certificate">证书(PEM 格式)。</param>/// <returns>证书颁发时间。</returns>public static DateTimeOffset ExportEffectiveTimeFromCertificate(string certificate){if (certificate == null) throw new ArgumentNullException(nameof(certificate));X509Certificate x509cert = ParseCertificatePemToX509(certificate);return new DateTimeOffset(x509cert.NotBefore);}/// <summary>/// <para>从 CRT/CER 证书中导出证书过期时间。</para>/// </summary>/// <param name="certificate">证书(PEM 格式)。</param>/// <returns>证书过期时间。</returns>public static DateTimeOffset ExportExpireTimeFromCertificate(string certificate){if (certificate == null) throw new ArgumentNullException(nameof(certificate));X509Certificate x509cert = ParseCertificatePemToX509(certificate);return new DateTimeOffset(x509cert.NotAfter);}}
}

C# 微信支付APIv3 SDK RSAUtility相关推荐

  1. 微信支付apiV3异常:The corresponding provider for the merchant already exists

    异常信息 java.lang.IllegalStateException: The corresponding provider for the merchant already exists. 原因 ...

  2. 实战微信支付 APIv3 接口(小程序的)

    开场白直接引用官方文档的吧. 为了在保证支付安全的前提下,带给商户简单.一致且易用的开发体验,我们推出了全新的微信支付 APIv3 接口. 为啥不用官方 SDK? 官方 SDK 不错,只是依赖 Apa ...

  3. php 工商银行公众号支付代码_微信支付PHP SDK —— 公众号支付代码详解

    在微信支付 开发者文档页面 下载最新的 php SDK 这里假设你已经申请完微信支付 1. 微信后台配置  如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请 ...

  4. java 庖丁解牛api_Java 微信支付 APIv3 平台证书的命令行下载工具

    Certificate Downloader Certificate Downloader 是 Java 微信支付 APIv3 平台证书的命令行下载工具.该工具可从 https://api.mch.w ...

  5. 一文搞懂「微信支付 Api-v3」接口规则所有知识点

    文章目录 简介 v2 与 v3 的区别 API 密钥设置 获取 API 证书 请求签名 示例代码 构造签名串 构造 HTTP 头中的 Authorization 获取证书序列号 通过工具获取 通过代码 ...

  6. 微信刷卡 sdk java_微信支付 Java SDK

    微信支付 Java SDK 对微信支付开发者文档中给出的API进行了封装. com.github.wxpay.sdk.WXPay类下提供了对应的方法: 方法名 说明microPay 刷卡支付 unif ...

  7. php 微信支付开发测试,微信支付PHP SDK —— 公众号支付代码详解

    在微信支付 开发者文档页面 下载最新的 php sdk 这里假设你已经申请完微信支付 1. 微信后台配置  如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请 ...

  8. Java接入微信支付APIV3(Native)

    Native支付是指商户系统按微信支付协议生成支付二维码,用户再用微信"扫一扫"完成支付的模式. 一.准备工作 微信商户平台 微信支付 - 中国领先的第三方支付平台 | 微信支付提 ...

  9. Java对接第三方支付渠道之微信支付APIV3版本

    提示:微信支付APIV3版本对接流程梳理,目前微信支付提供APIV3和APIV2两个版本,简而言之,V3版本的安全性比V2更高. Java对接第三方支付渠道之微信支付APIV3版本 一.接入指引 1. ...

最新文章

  1. php无表单上传文件,php – 来自表单的WP邮件附件,无文件管理器上传文件
  2. 去某大厂三面总监面,因为迟到了5分钟,面试官当着我的面把简历扔垃圾桶了...
  3. 写自己的一个pdo数据库操作框架
  4. 详解Linux多线程编程
  5. 谷歌浏览器flash_谷歌浏览器不支持Flash Player的问题
  6. Linux进程全解3——进程概念、进程ID、多进程调度原理
  7. php两个时间月数,PHP获得两个日期之间的月数
  8. linux中改localhome名称,修改 /var/lib/locales/supported.d/local 文件(使用 locale -a 命令查看系統中所有已配置的 locale)...
  9. 190120每日一句
  10. Web前端CSS颜色代码大全
  11. Win10安装Centos7双系统
  12. android移植大作游戏,这款steam移植的1GB大作,或许是今年最有氛围的悬疑游戏
  13. 计算机分析桁架受力,桁架的结构设计和受力分析
  14. 联通数据采集交换平台BDE的配置
  15. 圆桌:满足客人空座需求,准备最少的椅子,合理安排客人入座圆桌
  16. python培训总结心得
  17. Win10连接远程桌面失败
  18. SPM AC原点校正
  19. Zeus: Uber 开发的分布式的高扩展 Shuffle 服务组件
  20. 如何培养《未来架构师》(2)

热门文章

  1. POJ1159 回文串DP与MTE,滚动数组
  2. 通信中的计算机技术,计算机技术在通信中的应用研究.pdf
  3. 集成学习-task15
  4. MySQL 教程---菜鸟教程
  5. 【TG-02系列模组①】二次开发环境搭建,快速接入天猫精灵/亚马逊云
  6. 看它就够了,让你明白什么是【ajax】
  7. 软考高级系统架构设计师系列论文六十四:论软件测试方法和工具的选用
  8. hm模型下载及编码器分析
  9. 台式机电脑电源的使用
  10. ucosII 系统节拍、软件定时器节拍计算