11

証明書認証を使用するのは初めてです。商用パートナーは、XML Web サービスと HTTP サービスの 2 つのサービスを公開しています。.NET クライアントを使用して両方にアクセスする必要があります。

私が試したこと

0. 環境を整える

certmgr.exe を使用して、SSLCACertificates (ルートと 2 つの中間) とクライアント証明書をローカル マシン (win 7 プロフェッショナル) にインストールしました。

1. Web サービスの場合

  • 私はクライアント証明書 (der) を持っています。
  • サービスは .NET プロキシ経由で使用されます。

コードは次のとおりです。

OrderWSService proxy = new OrderWSService();
string CertFile = "ClientCert_DER.cer";

proxy.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(CertFile));
orderTrackingTO ot = new orderTrackingTO() { order_id = "80", tracking_id = "82", status = stateOrderType.IN_PREPARATION };
resultResponseTO res = proxy.insertOrderTracking(ot);

最後のステートメントで例外が報告されました: The request failed with an empty response

2. HTTP インターフェースの場合

  • これは、POST メソッドを介して呼び出さなければならない HTTPS インターフェースです。
  • HTTPS 要求は、HTTPWebRequest を使用して .NET クライアントから送信されます。

コードは次のとおりです。

string PostData = "MyPostData";

//setting the request
HttpWebRequest req;
req = (HttpWebRequest)HttpWebRequest.Create(url);
req.UserAgent = "MyUserAgent";
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(CertFile, "MyPassword")); 

//setting the request content
byte[] byteArray = Encoding.UTF8.GetBytes(PostData);
Stream dataStream = req.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

//obtaining the response
WebResponse res = req.GetResponse();
r = new StreamReader(res.GetResponseStream());

最後のステートメントで例外が報告されました: The request was aborted: Could not create SSL/TLS secure channel

3. 最後の試行: ブラウザーを使用する

Chrome で証明書をインストールした後、両方の URL にアクセスしようとすると、107 エラーが発生します。

Error 107 (net::ERR_SSL_PROTOCOL_ERROR)

ハマった。

4

1 に答える 1

7

以下は問題を特定するのに役立ちます。SSL 接続をテストする 2 つの方法を次に示します。1 つはサイトをテストし、もう 1 つは SSL が失敗した理由を特定するためのコールバック メソッドです。他に何もないとしても、なぜ失敗したのかをよりよく理解できるはずです。

メソッドが呼び出されると、証明書の選択ダイアログ ボックスがポップアップ表示されます。これを実際に実行する場合は、証明書ストアから自動的に読み取る必要があることは明らかです。これを入れた理由は、有効な証明書が見つからない場合、証明書のインストール方法に問題があることがわかるからです。

最善の方法は、このコードを単純なコンソール アプリに配置することです。

using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Net;

private static void CheckSite(string url, string method)
{
    X509Certificate2 cert = null;
    ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;

    X509Store store = new X509Store(StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
    X509Certificate2Collection certcollection = (X509Certificate2Collection)store.Certificates;
    // pick a certificate from the store
    cert = X509Certificate2UI.SelectFromCollection(certcollection, 
            "Caption",
            "Message", X509SelectionFlag.SingleSelection)[0];

    store.Close();

    HttpWebRequest ws = (HttpWebRequest)WebRequest.Create(url);
    ws.Credentials = CredentialCache.DefaultCredentials;
    ws.Method = method;
    if (cert != null)
        ws.ClientCertificates.Add(cert);

    using (HttpWebResponse webResponse = (HttpWebResponse)ws.GetResponse())
    {
        using (Stream responseStream = webResponse.GetResponseStream())
        {
            using (StreamReader responseStreamReader = new StreamReader(responseStream, true))
            {
                string response = responseStreamReader.ReadToEnd();
                Console.WriteLine(response);
                responseStreamReader.Close();
            }

            responseStream.Close();
        }
        webResponse.Close();
    }
}

/// <summary>
/// Certificate validation callback.
/// </summary>
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
    // If the certificate is a valid, signed certificate, return true.
    if (error == System.Net.Security.SslPolicyErrors.None)
    {
        return true;
    }

    Console.WriteLine("X509Certificate [{0}] Policy Error: '{1}'",
        cert.Subject,
        error.ToString());

    return false;
}
于 2012-06-27T11:00:08.940 に答える