在对接API过程中,需要用到对方提供的xxx.p12证书,以及对应的密码,解决方案如下:
/// <summary>
/// 带证书请求
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="method">请求方式</param>
/// <param name="content">请求的字符串</param>
/// <param name="headers">请求头</param>
/// <param name="certificatePath">证书路径</param>
/// <param name="certPassword">证书密码</param>
/// <returns>响应结果</returns>
/// <example>
/// Console.WriteLine(HttpWebRequestWithCertificate("https://host:port/path","POST", "{JsonData}", null,@"......\xxx.p12","123456"));
/// </example>
public string HttpWebRequestWithCertificate(string url, string method, string content, Dictionary<string, string> headers, string certificatePath, string certPassword)
{
string result = string.Empty;
try
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | (SecurityProtocolType)768 | (SecurityProtocolType)3072 | (SecurityProtocolType)0x300 | (SecurityProtocolType)0xC00;
ServicePointManager.ServerCertificateValidationCallback += (q, w, e, r) => r == SslPolicyErrors.None;
X509Certificate2 cer = new X509Certificate2(certificatePath, certPassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(content);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ClientCertificates.Add(cer);//必须先最先配置ClientCertificates字段,否则会报有关SSL/TLS错
request.ContentType = "application/json";
request.Method = method;
request.ContentLength = bytes.Length;
if (headers != null && headers.Count > 0)
{
foreach (var item in headers)
{
request.Headers.Add(item.Key, item.Value);
}
}
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
if (responseStream != null)
{
StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8;
result = reader.ReadToEnd().Trim();
reader.Close();
responseStream.Close();
request.Abort();
response.Close();
}
}
catch (Exception ex)
{
return ex.Message + ex.StackTrace;
}
return result;
}