2

C# を使用して、次の vbscript のチャンクを再現したいと思います。

sURL = "https://server/service.dll"
sXML = "<request version=""1.0""><ticket>generated ticket</ticket></request>"
dim winHTTPReq: Set winHTTPReq = CreateObject("WinHttp.WinHttpRequest.5.1")
winHttpReq.Open "POST", sURL, false
winHTTPReq.SetRequestHeader "Content-Type", "application/x-some-type"
sCertificate = "LOCAL_MACHINE\MY\Vendor Supplied PFX"
winHTTPReq.SetClientCertificate sCertificate
WinHttpReq.Send(sXML)
....

そうしようとする私の試みはすべて、a) 機能せず、b) 上記のスニペットよりも少し長くなりました。

var xml = (new XElement("request"
    , new XElement("ticket", "generated ticket")).ToString();

var cert = X509Certificate.CreateFromCertFile("c:\\Exported Vendor Supplied PFX.cer");
ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };
var request = (HttpWebRequest)WebRequest.Create("https://server/service.dll");
request.ClientCertificates.Add(cert);
request.ContentType = "application/x-some-type";
request.Method = "POST";

byte[] bytes = Encoding.UTF8.GetBytes(xml);
request.ContentLength = bytes.Length;

using (var requestStream = request.GetRequestStream())
requestStream.Write(bytes, 0, bytes.Length);

using (var response = (HttpWebResponse)request.GetResponse()) 
if (response.StatusCode != HttpStatusCode.OK) {
    string message = String.Format(
    "POST failed. Received HTTP {0}",
    response.StatusCode);
    throw new ApplicationException(message);
}

この後者のコードでは、常に 403 が返されます。理由はわかりませんが、許可に傾いています。cer ファイルから証明書を作成する前に、特に必要なことはありますか? winhttpcertcfg を介してアクセス許可を適用する必要がありますか?

私は元々、証明書 MMC を使用してインポートされた pfx を受け取りました。pfx をクライアント証明書として追加する方法はないようです。そのため、CreateFromCertFile() メソッドで使用するために pfx を DER x509 cer としてエクスポートしました。pfx のみを使用する方法はありますか?

もちろん、元の VBScript は問題なく動作します。それを変換するには何が必要かを知りたいだけです。それほど難しくはないように思えますが、これまでのところ、少し苦労しました。

[アップデート]

どうやら、ディスク上で pfx を使用することは可能です (パスワードがあれば) が、[これ]http://support.microsoft.com/kb/948154 は、証明書ストアに依存する方がよいことを示唆しているようです。これは元の vbscript が行っていたことと似ているため、ストアから証明書を取得するように上記のコードを変更しました。

var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

X509Certificate2 cert = store.Certificates.Find(X509FindType.FindBySubjectName
, "XXXX", false)[0];

WinHttpCertCfg ツールを使用して、許可された「Everyone」アクセスを証明書に追加しました。まだ運がありません。残念ながら、これもサーバーから 403 を返します。コードを見ていくと、証明書が見つかり、正常に作成されていることがわかります。クライアント証明書として追加されていることも確認できます。なんらかの理由で、HttpWebResponse を使用してうまくいきませんでした。

ただし、相互運用機能を使用すると問題なく動作します。フレームワークにネイティブではないものに依存するのは嫌いですが、WinHttpRequest コンポーネントは非常に使いやすいようです。約 1/4 のコードで同じことを達成でき、これはアプリの残りの部分とうまく統合されます。

xml = "<request version=\"1.0\"><ticket>generated ticket</ticket></request>";
var req = new WinHttp.WinHttpRequest();
req.Open("POST", "https://server/service.dll", false);
req.SetRequestHeader("Content-Type", "application/x-some-type");
req.SetClientCertificate(@"LOCAL_MACHINE\MY\Vendor Supplied PFX");
req.Send(xml);
Console.WriteLine(string.Format("{0} {1}", req.Status, req.StatusText));
Console.WriteLine(req.ResponseText);
4

0 に答える 0