最近项目中需要通过https对接客户的服务器API,客户给的格式为.pem和.key的证书和私钥文件,然后我没有找到C#通过证书和密钥两个文件创建证书的方法,要通过X509Certificate2创建证书只能是引入一个文件,最后找到方法如下:
代码:
//2.定义方法:
private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
//为了通过证书验证,总是返回true
return true;
}
/// <summary>
/// Https 请求函数 暂时只支持GET PUT POST
/// </summary>
/// <param name="GetOrPost"></param>
/// <param name="Url"></param>
/// <param name="RequestInfo"></param>
/// <param name="ResponseInfo"></param>
/// <param name="TimeOutMs"></param>
/// <returns></returns>
public static int HttpRequest(string GetOrPost, string Url, string RequestInfo, ref string ResponseInfo, int TimeOutMs)
{
try
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(RemoteCertificateValidate);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
ServicePointManager.Expect100Continue = false;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
X509Certificate2 cer = new X509Certificate2(@".\client.pfx", "123456", X509KeyStorageFlags.DefaultKeySet);
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.MaxAllowed);
store.Remove(cer);
store.Add(cer);
store.Close();
request.UseDefaultCredentials = true;
request.PreAuthenticate = true;
request.Credentials = CredentialCache.DefaultCredentials;
request.ClientCertificates.Add(cer);
request.Method = GetOrPost;
request.KeepAlive = false;
// request.CookieContainer = CookieContainer;
request.ProtocolVersion = HttpVersion.Version11;
request.AllowAutoRedirect = false;
request.Timeout = TimeOutMs;
//3.在WebRequest请求之前调用:
ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;
if (GetOrPost == "PUT")
{
request.ContentType = "application/json";
int RequestLength = Encoding.UTF8.GetByteCount(RequestInfo);
Stream RequestStream = request.GetRequestStream();
RequestStream.Write(Encoding.UTF8.GetBytes(RequestInfo), 0, RequestLength);
RequestStream.Close();
}
else if (GetOrPost == "POST")
{
request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
int RequestLength = Encoding.UTF8.GetByteCount(RequestInfo);
Stream RequestStream = request.GetRequestStream();
RequestStream.Write(Encoding.UTF8.GetBytes(RequestInfo), 0, RequestLength);
RequestStream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream ResponseStream = response.GetResponseStream();
StreamReader StreamReader = new StreamReader(ResponseStream, Encoding.UTF8);
ResponseInfo = StreamReader.ReadToEnd();
StreamReader.Close();
response.Close();
return 0;
}
catch (Exception ex)
{
ResponseInfo = "HTTPS Error Message :" + ex.Message;
return -1;
}
}
函数调用方法:HTTPS.HttpRequest(“GET”, uri_GetData, null, ref ReviveData, 40000);
X509Certificate2类创建证书文件必须使用同时包含证书、公钥、私钥的证书文件格式;
客户给的.pem和.key文件,必须转化格式才可以直接使用。
.pem包含公钥和证书,.key包含私钥,需要通过OpenSSL将其转化成同时包含证书、公钥、私钥的证书文件格式。
转换方法:
打开OpenSSL,输入pkcs12 -export -out D:/client.pfx -inkey D:/client.key -in D:/client.pem,
会提示输出两次密码,此密码为生成的.pfx格式证书文件的密码;
D:/client.key、D:/client.pem指示key和pem路径和文件名,可以根据实际情况修改,D:/client.pfx为生成文件的路径和文件名;
密码输入完成之后,按下enter,自动转换成功:
X509Certificate2 cer = new X509Certificate2(@".\client.pfx", “123456”, X509KeyStorageFlags.DefaultKeySet);
".\client.pfx"为证书文件路径和文件名,"123456"为证书密码,即通过OpenSSL转换时输入输入的密码;