微信支付特约商户进件中base64格式图片上传
微信图片上传接口地址:https://api.mch.weixin.qq.com/v3/merchant/media/upload
1、上传方法
1 using HttpHandlerDemo;
2 using Newtonsoft.Json;
3 using System;
4 using System.Collections.Generic;
5 using System.IO;
6 using System.Linq;
7 using System.Net;
8 using System.Net.Http;
9 using System.Net.Http.Headers;
10 using System.Security.Cryptography;
11 using System.Text;
12 using HttpHandler = Lib.HttpHandler;
13
14 namespace API
15 {
16 public class Helper
17 {
18 public static string UploadImg(string b64)
19 {
20 byte[] data = Convert.FromBase64String(b64);
21 //证书本地路径
22 string certPath = @"***";
23 //证书秘钥
24 string certPwd = "***";
25 //商户号
26 string mchid = "***";
27 //证书编号
28 string serialNo = "***";
29 string boundary = string.Format("--{0}", DateTime.Now.Ticks.ToString("x"));
30 var sha256 = Sha256(data);
31 var meta = new
32 {
33 sha256 = sha256,
34 filename = Guid.NewGuid().ToString().Replace("-", "") + ".png"
35 };
36 var json = JsonConvert.SerializeObject(meta);
37 var httpHandler = new HttpHandler(mchid, serialNo, certPath, certPwd, json);
38 HttpClient client = new HttpClient(httpHandler);
39 using (var content = new MultipartFormDataContent(boundary))
40 {
41 content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); //这里必须添加
42 content.Add(new StringContent(json, Encoding.UTF8, "application/json"), "\"meta\""); //这里主要必须要双引号
43
44 var byteArrayContent = new ByteArrayContent(data);
45 byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
46 content.Add(byteArrayContent, "\"file\"", "\"" + meta.filename + "\""); //这里主要必须要双引号
47 try
48 {
49 using (var response = client.PostAsync("https://api.mch.weixin.qq.com/v3/merchant/media/upload", content)) //上传
50 using (var responseContent = response.Result.Content)
51 {
52 string responseBody = responseContent.ReadAsStringAsync().Result;
53 var dic = Newtonsoft.Json.Linq.JObject.Parse(responseBody);
54 return dic["media_id"].ToString();
55 }
56 }
57 catch (Exception e)
58 {
59 return null;
60 }
61
62
63 }
64 }
65
66 public static string Sha256(byte[] bytes)
67 {
68 byte[] hash = SHA256Managed.Create().ComputeHash(bytes);
69 StringBuilder builder = new StringBuilder();
70 for (int i = 0; i < hash.Length; i++)
71 {
72 builder.Append(hash[i].ToString("X2"));
73 }
74 return builder.ToString();
75 }
76
77 }
78 }
2、Lib.HttpHandler代码
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Net.Http;
5 using System.Net.Http.Headers;
6 using System.Security.Authentication;
7 using System.Security.Cryptography;
8 using System.Security.Cryptography.X509Certificates;
9 using System.Text;
10 using System.Threading;
11 using System.Threading.Tasks;
12
13 namespace Lib
14 {
15 /// <summary>
16 /// 头文件
17 /// </summary>
18 public class HttpHandler : DelegatingHandler
19 {
20 private readonly string merchantId;
21 private readonly string serialNo;
22 private readonly string certPath;
23 private readonly string certPwd;
24 private readonly string json;
25 /// <summary>
26 /// 构造方法
27 /// </summary>
28 /// <param name="merchantId">商户号</param>
29 /// <param name="merchantSerialNo">证书序列号</param>
30 /// <param name="certPath">证书路径</param>
31 /// <param name="certPwd">证书秘钥</param>
32 /// <param name="json">签名json数据,默认不需要传入,获取body内容,如传入签名传入参数上传图片时需传入</param>
33 public HttpHandler(string merchantId, string merchantSerialNo, string certPath, string certPwd, string json = "")
34 {
35
36 HttpClientHandler handler = new HttpClientHandler();
37 handler.ClientCertificateOptions = ClientCertificateOption.Manual;
38 handler.SslProtocols = SslProtocols.Tls12;
39 try
40 {
41 handler.ClientCertificates.Add(new X509Certificate2(certPath, certPwd,
42 X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet));
43 }
44 catch (Exception e)
45 {
46 throw new Exception("ca err(证书错误)");
47 }
48 handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
49 handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
50 InnerHandler = handler;
51 this.merchantId = merchantId;
52 this.serialNo = merchantSerialNo;
53 this.certPath = certPath;
54 this.certPwd = certPwd;
55 this.json = json;
56 }
57
58 protected async override Task<HttpResponseMessage> SendAsync(
59 HttpRequestMessage request,
60 CancellationToken cancellationToken)
61 {
62 var auth = await BuildAuthAsync(request);
63 string value = $"WECHATPAY2-SHA256-RSA2048 {auth}";
64 request.Headers.Add("Authorization", value);
65 request.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36");
66 MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeader = new MediaTypeWithQualityHeaderValue("application/json");
67 request.Headers.Accept.Add(mediaTypeWithQualityHeader);
68 request.Headers.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
69 return await base.SendAsync(request, cancellationToken);
70 }
71
72 protected async Task<string> BuildAuthAsync(HttpRequestMessage request)
73 {
74 string method = request.Method.ToString();
75 string body = "";
76 if (method == "POST" || method == "PUT" || method == "PATCH")
77 {
78 if (!string.IsNullOrEmpty(json))
79 body = json;
80 else
81 {
82 var content = request.Content;
83 body = await content.ReadAsStringAsync();
84 }
85 }
86 string uri = request.RequestUri.PathAndQuery;
87 var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
88 string nonce = Guid.NewGuid().ToString("n");
89 string message = $"{method}\n{uri}\n{timestamp}\n{nonce}\n{body}\n";
90
91 string signature = Sign(message);
92 return $"mchid=\"{merchantId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{serialNo}\",signature=\"{signature}\"";
93 }
94
95 //SHA256withRSA
96 public string Sign(string str)
97 {
98 byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
99 var sha256 = new SHA256CryptoServiceProvider();
100 byte[] rgbHash = sha256.ComputeHash(bt);
101
102 try
103 {
104 var rsa = GetPrivateKey();
105 var key = new RSACryptoServiceProvider();
106 var paras = rsa.ExportParameters(true);
107 key.ImportParameters(paras);
108 RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
109 formatter.SetHashAlgorithm("SHA256");
110 byte[] inArray = formatter.CreateSignature(rgbHash);
111 return Convert.ToBase64String(inArray);
112 }
113 catch (Exception e)
114 {
115 return e.Message;
116 }
117 }
118
119 private RSACryptoServiceProvider GetPrivateKey()
120 {
121 var pc = new X509Certificate2(certPath, certPwd, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
122 return (RSACryptoServiceProvider)pc.PrivateKey;
123 }
124
125 }
126 }
仅此记录一下
微信支付特约商户进件中base64格式图片上传的更多相关文章
- Aps.net中基于bootstrapt图片上传插件的应用
Aps.net中基于bootstrapt图片上传插件的应用 在最近的项目中需要使用一个图片上传的功能,而且是多张图片同时上传到服务器的文件夹中,将图片路径存放在数据库中.为了外观好看使用了bootst ...
- 从web编辑器 UEditor 中单独提取图片上传,包含多图片单图片上传以及在线涂鸦功能
UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码.(抄的...) UEditor是非常好用的富文 ...
- ssm项目中KindEditor的图片上传插件,浏览器兼容性问题
解决办法: 原因:使用@ResponseBody注解返回java对象,在浏览器中是Content-Type:application/json;charset=UTF-8 我们需要返回字符串(Strin ...
- hybird app项目实例:安卓webview中HTML5拍照图片上传
应用的平台环境:安卓webview: 涉及的技术点: (1) <input type="file" > :在开发中,安卓webview默认点击无法调用文件选择与相机拍照 ...
- PHP base64多图片上传
// 多图片上传,base64 public function upload_multi() { $pic = $_POST['pic']; if (!$pic) { $this->json-& ...
- Django中怎么做图片上传--图片展示
1.首先是html页面的form表单的三大属性,action是提交到哪,method是提交方式,enctype只要有图片上传就要加这个属性 Django框架自带csrf_token ,所以需要在前端页 ...
- MVC 中使用kindEditor 图片上传在IE 上进行上传出现的问题
在IE 上使用KindEditor 进行单张图片上传的时候会出现一个下载安全警告,这样将会造成图片上传失败,出现的错误页面:
- 在SSM框架中如何将图片上传到数据库中
今天我们来看看SSM中如何将图片转换成二进制,最后传入到自己的数据库中,好了,废话不多说,我们开始今天的学习,我这里用的编辑器是IDEA 1.导入图片上传需要的jar依赖包 1 <depende ...
- html5 图片转为base64格式异步上传
因为有这个需求(移动端),所以就研究了一下,发现还挺不错的.这个主要是用了html5的API,不需要其他的JS插件,不过只有支持html5的浏览器才行,就现在而言应该大部份都支持的.<!DOCT ...
随机推荐
- 零基础小白Python入门必看:面向对象之典型魔术方法
- SpringBoot 优化
- .NET Standard 类库的使用技巧
系列目录 [已更新最新开发文章,点击查看详细] 在前一篇博客<.NET Standard中配置TargetFrameworks输出多版本类库>中详细介绍了如何创建.配置.条件编译. ...
- 详解工程师不可不会的LRU缓存淘汰算法
大家好,欢迎大家来到算法数据结构专题,今天我们和大家聊一个非常常用的算法,叫做LRU. LRU的英文全称是Least Recently Used,也即最不经常使用.我们看着好像挺迷糊的,其实这个含义要 ...
- CVE-2010-2883-CoolType.dll缓冲区溢出漏洞分析
前言 此漏洞是根据泉哥的<漏洞战争>来学习分析的,网上已有大量分析文章在此只是做一个独立的分析记录. 复现环境 操作系统 -> Windows XP Sp3 软件版本 -> A ...
- 实时离线一体化在资产租赁saas服务中使用
流水查询需求 需求第一期: 基于TB级的在线数据,支持缴费帐单明细在线查询.大家都知道,像银行帐单流水一样,查几年的流水是常有的事. 支持的维度查询:帐期.欠费状态.日期范围.费用科目类型.房屋分类. ...
- spring boot:给接口增加签名验证(spring boot 2.3.1)
一,为什么要给接口做签名验证? 1,app客户端在与服务端通信时,通常都是以接口的形式实现, 这种形式的安全方面有可能出现以下问题: 被非法访问(例如:发短信的接口通常会被利用来垃圾短信) 被重复访问 ...
- C++ Primer第5版 第三章课后练习
练习3.1 #include <iostream> using namespace std; int main() { int sum = 0, val = 50; while (val ...
- oozie.action.hadoop.LauncherException: IO error Connection timed out: no further information
本文主要针对使用CDH平台的HUE时候碰到两类问题,最终问题并没有得到很好的解决,只是提供了一种绕行方式,欢迎知道的朋友补充. ## **NO 1: HUE执行jar包** > 第一种报错 or ...
- buuctf-misc-[BJDCTF 2nd]圣火昭昭-y1ng 1
开局一张图片,flag全靠猜,那这个是不是和outguess工具有关呢?于是我们显示查看了图片的详细信息 看到是新佛曰,于是我们用新佛曰论禅解密:http://hi.pcmoe.net/buddha. ...