11

どうやら、以前の投稿で間違った質問をしていたようです。X.509 証明書で保護された Web サービスを、安全な Web サイト ( https://.. .) として実行しています。会社のルート CA によって発行されたクライアントのマシン証明書 (X.509 も) を使用して、クライアント マシンがサービスの使用を許可されていることをサーバーに確認したいと考えています。これを行うには、証明書を調べて識別機能を探し、それをデータベースに保存されている値 (おそらく拇印?) と照合する必要があります。

ローカル証明書ストアから証明書を取得するために使用するコードを次に示します ( http://msdn.microsoft.com/en-us/magazine/cc163454.aspxから直接引用):

 public static class SecurityCertificate
{
    private static X509Certificate2 _certificate = null;

    public static X509Certificate2 Certificate
    {
        get { return _certificate; }
    }

    public static bool LoadCertificate()
    {
        // get thumbprint from app.config
        string thumbPrint = Properties.Settings.Default.Thumbprint;
        if ( string.IsNullOrEmpty( thumbPrint ) )
        {
            // if no thumbprint on file, user must select certificate to use
            _certificate = PickCertificate( StoreLocation.LocalMachine, StoreName.My );
            if ( null != _certificate )
            {
                // show certificate details dialog
                X509Certificate2UI.DisplayCertificate( _certificate );
                Properties.Settings.Default.Thumbprint = _certificate.Thumbprint;
                Properties.Settings.Default.Save();
            }
        }
        else
        {
            _certificate = FindCertificate( StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, thumbPrint );
        }

        if ( null == _certificate )
        {
            MessageBox.Show( "You must have a valid machine certificate to use STS." );
            return false;
        }

        return true;
    }

    private static X509Certificate2 PickCertificate( StoreLocation location, StoreName name )
    {
        X509Store store = new X509Store( name, location );
        try
        {
            // create and open store for read-only access
            store.Open( OpenFlags.ReadOnly );

            X509Certificate2Collection coll = store.Certificates.Find( X509FindType.FindByIssuerName, STSClientConstants.NBCCA, true );
            if ( 0 == coll.Count )
            {
                MessageBox.Show( "No valid machine certificate found - please contact tech support." );
                return null;
            }

            // pick a certificate from the store
            coll = null;
            while ( null == coll || 0 == coll.Count )
            {
                coll = X509Certificate2UI.SelectFromCollection(
                        store.Certificates, "Local Machine Certificates",
                        "Select one", X509SelectionFlag.SingleSelection );
            }

            // return first certificate found
            return coll[ 0 ];
        }
        // always close the store
        finally { store.Close(); }
    }

    private static X509Certificate2 FindCertificate( StoreLocation location, StoreName name, X509FindType findType, string findValue )
    {
        X509Store store = new X509Store( name, location );
        try
        {
            // create and open store for read-only access
            store.Open( OpenFlags.ReadOnly );

            // search store
            X509Certificate2Collection col = store.Certificates.Find( findType, findValue, true );

            // return first certificate found
            return col[ 0 ];
        }
        // always close the store
        finally { store.Close(); }
    }

次に、次のように証明書を送信ストリームに添付します。

public static class ServiceDataAccess
{    
    private static STSWebService _stsWebService = new STSWebService();

    public static DataSet GetData(Dictionary<string,string> DictParam, string action)
    {
        // add the machine certificate here, the first web service call made by the program (only called once)
        _stsWebService.ClientCertificates.Add( SecurityCertificate.Certificate );
        // rest of web service call here...
    }
}

私の質問はこれです - Web サービスコードで証明書を「取得」するにはどうすればよいですか? 私が遭遇したほとんどのサンプル コード スニペットでは、カスタム検証を行う方法をカバーしており、そこに GetCertificate() 呼び出しが含まれています。

私のメイン クラスは WebService を継承しているため、Context.Request.ClientCertificate を使用して証明書を取得できますが、これは X509Certificate2 ではなく HttpClientCertificate です。HttpContext でも同じ結果が得られます。他のアプローチはすべて、Web 構成コードを使用して事前定義された検証コードを呼び出しますが、カスタム C# メソッドを呼び出して検証を行う方法についての手がかりはありません。

4

2 に答える 2

14

似たようなことをしたことを覚えていますが、しばらく経ちましたが、Web サービスでこれを試しましたか:

X509Certificate2 cert = new X509Certificate2(Context.Request.ClientCertificate.Certificate);
于 2009-05-21T17:49:29.263 に答える
2

証明書をユーザーに関連付ける方法については、キーに関連付けられているユーザーの ID が適切であると仮定すると (証明書が信頼されたルートに戻って検証され、取り消されていないため)、関連付ける必要があります。証明書によってユーザーに要求される ID。サブジェクト DN の LDAP 文字列形式を使用し、それを調べて (cn=Username,ou=Department...)、ローカル ID を特定することができます。これは、カードの紛失や証明書の自然な失効などにより、ユーザーがキー/証明書を再生成した場合に回復力があります。これは、2 つの CA が同じサブジェクト名を持つ 2 つの証明書を 2 人の異なる人に発行しないという事実に依存しています。

証明書が MS CA によって発行された場合、実質的にドメイン ログオン名である UPN が含まれている可能性があります。

あるいは、ユーザーの ID を実際の証明書に結び付けたい場合、通常の方法は、発行者名と証明書のシリアル番号を保存することです。CA は、証明書ごとに一意のシリアル番号を発行する必要があります。CA によっては、シリアル番号が大きくなる可能性があることに注意してください。ただし、この方法を使用しても、ユーザー証明書が再発行されるたびにデータベース内の証明書の詳細を更新する必要があるというわけではありません。

于 2009-10-01T01:29:32.357 に答える