C# 使用证书文件通过 SSL 连接到 Web 服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8758442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 04:17:26  来源:igfitidea点击:

Using certificate file to connect to webservice over SSL

c#.netsslwindows-servicesssl-certificate

提问by user1013552

I am developing windows service in C# which invokes webservice methods. I must use SSL to connect to webservice. I have recieved from publisher p12 file with certificate. The file is password protected. To use Import method to use this certificate. Everything is working fine, but I do not like this method - I have password harcoded in my app. When publisher changes certificate I must rewrite code(changing the password to new one). Is there any way not to harcode password to .p12 file or use other option(.cer file)?

我正在用 C# 开发 Windows 服务,它调用 webservice 方法。我必须使用 SSL 连接到网络服务。我已从出版商处收到带有证书的 p12 文件。该文件受密码保护。要使用导入方法来使用此证书。一切正常,但我不喜欢这种方法 - 我在我的应用程序中对密码进行了硬编码。当发布者更改证书时,我必须重写代码(将密码更改为新密码)。有没有办法不将密码硬编码到 .p12 文件或使用其他选项(.cer 文件)?

采纳答案by Eugene Mayevski 'Callback

PKCS#12 file is provided to you as it is a natural way to transport certificates together with private keys. You can use one of the following:

向您提供了 PKCS#12 文件,因为它是将证书与私钥一起传输的自然方式。您可以使用以下方法之一:

  • convert it to format you like and store the way you like
  • convert it to passwordless PFX
  • import it to computer's certificate storage and use it this way
  • 将其转换为您喜欢的格式并以您喜欢的方式存储
  • 将其转换为无密码 PFX
  • 将其导入计算机的证书存储并以这种方式使用

But all those methods (together with keeping a hardcoded password) provide no real protection to the private key and thus are not usable if you distribute the application to outside of your organization.

但是所有这些方法(连同保持硬编码的密码)都没有为私钥提供真正的保护,因此如果您将应用程序分发到组织外部,则无法使用。

回答by Andreas Koch

What you could do is something like this:

你可以做的是这样的:

  1. Install the SSL certificate into your local machine certificate store (using the Microsoft Management Console "MMC")
  2. Extract the certificates thumbprint (e.g. "748681ca3646ccc7c4facb7360a0e3baa0894cb5")
  3. Use a function which fetches you the certificate from the local certificate store for the given thumbprint.
  4. Provide the SSL certificate when calling your web service.
  1. 将 SSL 证书安装到本地机器证书库中(使用 Microsoft 管理控制台“MMC”)
  2. 提取证书指纹(例如“748681ca3646ccc7c4facb7360a0e3baa0894cb5”)
  3. 使用从本地证书存储中获取给定指纹的证书的函数。
  4. 在调用 Web 服务时提供 SSL 证书。
private static X509Certificate2 GetCertificateByThumbprint(string certificateThumbPrint, StoreLocation certificateStoreLocation) {
    X509Certificate2 certificate = null;

    X509Store certificateStore = new X509Store(certificateStoreLocation);
    certificateStore.Open(OpenFlags.ReadOnly);


    X509Certificate2Collection certCollection = certificateStore.Certificates;
    foreach (X509Certificate2 cert in certCollection)
    {
        if (cert.Thumbprint != null && cert.Thumbprint.Equals(certificateThumbPrint, StringComparison.OrdinalIgnoreCase))
        {
            certificate = cert;
            break;
        }
    }

    if (certificate == null)
    {
        Log.ErrorFormat(CultureInfo.InvariantCulture, "Certificate with thumbprint {0} not found", certificateThumbPrint);
    }

    return certificate;
}

public string GetServiceResponse() {
    string WebSvcEndpointConfigurationName = "WebServiceEndpoint";
    Uri webSvcEndpointAddress = new Uri("http://www.example.com/YourWebService.svc");
    string webSvcCertificateThumbPrint = "748681ca3646ccc7c4facb7360a0e3baa0894cb5";

    string webSvcResponse = null;
    SomeWebServiceClient webServiceClient = null;

    try
    {
        webServiceClient = new SomeWebServiceClient(WebSvcEndpointConfigurationName, new EndpointAddress(webSvcEndpointAddress));
        webServiceClient.ClientCredentials.ClientCertificate.Certificate = GetCertificateByThumbprint(webSvcCertificateThumbPrint, StoreLocation.LocalMachine);

        webSvcResponse = webServiceClient.GetServiceResponse();
    }
    catch (Exception ex)
    {
    }
    finally
    {
        if (webServiceClient != null)
        {
            webServiceClient.Close();
        }
    }
    return webSvcResponse;
}