4

私は開発者向けに多くのサーバーとPCを使用しています。サーバーはwin2003、PC開発者はWindowsXPです。

preiis01という名前のサーバーWin2003の実稼働環境では、社内の他のユーザーが、サーバーpreiis01にログインするために他のユーザー(domainCompany \ adminsystems)を使用してクライアント証明書をインストールします。

すべての管理者は、ユーザー「domainCompany \ adminsystems」を使用してサーバーpreiis01にログインします(ターミナルサーバー、Windows XPのリモートデスクトップを使用)。

管理者ユーザーはdomainCompany\adminsystems "で、証明書をインストールします。

管理者ユーザーは次のようにインストールします。

「domainCompany\adminsystems」証明書のようなセッションログインはPFXファイルです。PFXをインストールし、ウィザードを使用してください。キープライベートはエクスポートをチェックしません。パスワードを入力してインストールします。

AppPool IdentityであるアプリケーションWebがあります:NETWORKSERVICEアカウント。

WebサーバーはIIS6.0です。

preiis01では、

その管理ユーザーは、mmc->スナップイン->ローカルマシンの証明書を実行します。ノード->個人->証明書で、彼はクライアント証明書を見ていました:

ENTIDAD COMPANYINSURESAに発行-CIFA93-NOMBRESURNAME1 NAME1

FNMT Clase2CAによって発行されました

証明書のプロパティでは、拇印: "93 bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c413"

その管理者ユーザーは次のコマンドを実行します。

winhttpcertcfg.exe LOCAL_MACHINE \ My -s "ENTIDAD COMPANY INSURE SA --CIF A93 --NOMBRE SURNAME1 NAME1" -g-a"ネットワークサービス"

結果は次のとおりです。

一致する証明書:

CN = ENTIDAD COMPANY INSURE SA-CIF A93-NOMBRE SURNAME1 NAME1

OU = 703015476

OU=FNMTクラス2CA

O = FNMT

C = ES

アカウントに秘密鍵アクセスを許可する:NT AUTHORITY \ NETWORK SERVICE

ここで、adminユーザーは次のコマンドを実行します。

winhttpcertcfg.exe -l -c LOCAL_MACHINE \ My -s "ENTIDAD COMPANY INSURE SA --CIF A93 --NOMBRE SURNAME1 NAME1"

結果は次のとおりです。

一致する証明書:

CN = ENTIDAD COMPANY INSURE SA-CIF A93-NOMBRE SURNAME1 NAME1

OU = 700012476

OU=FNMTクラス2CA

O = FNMT

C = ES

秘密鍵にアクセスできる追加のアカウントとグループには、domainCompany \ adminsystems NT AUTHORITY \ SYSTEM BUILTIN \ Administrators NT AUTHORITY \NETWORKSERVICEが含まれます。

これで、サーバーWin2003、IIS 6.0のアプリケーションWebのaspxページに、次のコードがあります。

注:X509Certificate2.HasPrivateKeyAccess()の値は、「ENTIDAD COMPANY INSURE SA-CIF A93-NOMBRE SURNAME1NAME1」証明書の場合はNO(false)です。

ASP.NETアプリケーションは、ID :: NT AUTHORITY \NETWORKSERVICEを使用して実行されます

lbInfo.Text += "<br/><br/>ASP.NET application executes using the identity :: <b>" + WindowsIdentity.GetCurrent().Name + "</b><br>";


            var store = new X509Store(StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            Certificates = store.Certificates;
            repeater1.DataSource = Certificates;
            repeater1.DataBind();

            var nombreCertificado = "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1";

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

            X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindBySubjectName, nombreCertificado, false);

            if (col.Count > 0)
            {
                X509Certificate2 certificate = col[0];
                store.Close();
                Message.Text = "Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;

                FirmarConCertificado(nombreCertificado, certificate);

            }
            else
            {
                store.Close();
                Message.Text = "El certificado " + nombreCertificado + " no esta instalado en la máquina";
            }


public void FirmarConCertificado(string nombreCertificado, X509Certificate2 certificate)
{
    try
    {
 var mensaje = "Datos de prueba";
                System.Text.Encoding enc = System.Text.Encoding.Default;
                byte[] data = enc.GetBytes(mensaje);

                var contentInfo = new System.Security.Cryptography.Pkcs.ContentInfo(data);
                var signedCms = new System.Security.Cryptography.Pkcs.SignedCms(contentInfo, true);

                var cmsSigner = new System.Security.Cryptography.Pkcs.CmsSigner(certificate);

                //  Sign the CMS/PKCS #7 message
                signedCms.ComputeSignature(cmsSigner);

                //  Encode the CMS/PKCS #7 message
               var ret = Convert.ToBase64String(signedCms.Encode());

 Message.Text += "Firmado con Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;
 }
 catch (Exception ex)
 {
 Message.Text = "Error al firmar con certificado: " + ex.ToString();
 Message.Text += "<br /><br />InnerException: " + ex.InnerException;
 }

}

コードが失敗し、次のエラーが発生します:復号化用の証明書と秘密鍵が見つかりません。

エラー行は次のとおりです。signedCms.ComputeSignature(cmsSigner);

エラーalfirmarconcertificado:System.Security.Cryptography.CryptographicException:復号化用の証明書と秘密鍵が見つかりません。

System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner signer、ブールサイレント)at System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner signer、ブールサイレント)atSystem.Security.Cryptography.Pkcs.SignedCms.ComputeSignature (CmsSigner署名者、ブールサイレント)c:\ Company \ App \ Test \ TestのASP.dgsfp_test_testcert_aspx.FirmarConCertificado(String nombreCertificado、X509Certificate2証明書)のSystem.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner署名者) 242行目

次に、管理者ユーザー(証明書をインストールする人)が次のコマンドを実行します。

FindPrivateKey My LocalMachine -t "93 bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c4 13" –c

FindPrivateKey My LocalMachine -n​​ "ENTIDAD COMPANY INSURE SA --CIF A93 --NOMBRE SURNAME1 NAME1" –a

FindPrivateKey My LocalMachine -n​​ "CN = ENTIDAD COMPANY INSURE SA --CIF A93 --NOMBRE SURNAME1 NAME1" –a

3つのコマンドすべての結果は同じです。

FindPrivateKeyは、ユーザーがX.509証明書の秘密鍵ファイルの場所を見つけるのに役立ちます。

使用法:FindPrivateKey [{{-n} | {-t}} [-f | -d | -a]]

証明書のサブジェクト名

証明書のフィンガープリント(certmgr.exeを使用して取得します)

-f出力ファイル名のみ

-d出力ディレクトリのみ

-出力絶対ファイル名(例:FindPrivateKey My CurrentUser -n "CN = John Doe"

例:FindPrivateKey My LocalMachine -t "03 33 98 63 d0 47 e7 48 71 33 62 64 76 5 c 4c 9d 42 1d 6b 52" -c

FindPrivateKeyは何も取得しませんが、winhttpcertcfg.exe -lは正常に機能します(証明書と一致します)

winhttpcertcfg.exeツールを使用してネットワークサービスユーザーに特権を付与し、コードASP.NET(ネットワークサービスアカウントで実行)で証明書が見つかりました。ただし、証明書を使用して署名すると失敗します。

誰かが私たちにいくつかの情報や提案を与えることができれば

アップデート:

ドメイン「domainCompany\Pre_Certificado」のユーザーは、ストアローカルマシンに証明書をインストールします。

domainCompany \ Pre_Certificadoは、IIS_WPGグループの管理者であり、ローカルポリシーがあります:「サービスとしてログオン」</ p>

IIS6.0でAppPoolIdentityを次のように構成します:domainCompany \ Pre_Certificado

ASP.NETアプリケーションは、ID :: domainCompany\Pre_Certificadoを使用して実行されます

AppPoolをリサイクルしてアプリケーションを実行すると、System.Security.Cryptography.CryptographicExceptionが発生します:復号化用の証明書と秘密鍵が見つかりません

もう一度テストする場合は、domainCompany \ Pre_Certificadoユーザーを使用してサーバーIISにセッションにログインし、ASP.NETアプリケーションでページを呼び出します。すべて問題ありません。

(注:ターミナルサーバーを使用してサーバーIISにログインします)

ただし、サーバーIIS(ユーザー:domainCompany \ Pre_Certificado)でセッションをログオフすると、同じエラーが発生します。

System.Security.Cryptography.CryptographicException:復号化用の証明書と秘密鍵が見つかりません

助言がありますか ??

4

3 に答える 3

5

最初の2つの手順は、IIS 7.5の場合と同じように実行します(ここをクリック)。

  1. 証明書を作成/購入します。秘密鍵があることを確認してください。
  2. 証明書を「ローカルコンピュータ」アカウントにインポートします。証明書MMCを使用するのが最適です。必ず「秘密鍵のエクスポートを許可する」にチェックを入れてください
  3. 管理者として以下のコマンドを実行します。以下を置き換えます。

    • [Subject]を証明書のsubjectに置き換え、スペースが含まれている場合は引用符を使用します。同じ主題で始まる別の証明書がない限り、最初の単語を入力することもできると思います。
    • [Store]を、インポートした証明書ストアに置き換えます。デフォルトでは、IIS 6では「ROOT」または「MY」、つまり「LOCAL_MACHINE\ROOT」または「LOCAL_MACHINE\MY」です。
    • [computername]をコンピューターの名前に置き換えます。[computernam]の「。\」表記、つまり「。\ NETWORK SERVICE」を使用できる場合がありますが、私は試していません。

winhttpcertcfg.exe -g -a "[computername] \ NETWORK SERVICE" -c LOCAL_MACHINE \ [Store] -s "[Subject]"

注:「NETWORKSERVICE」以外のIDでASP.NETアプリケーションプールを実行している場合は、上記のコマンドの「NETWORKSERVICE」をIISアプリケーションプールを実行しているIDに変更する必要があります。

于 2010-11-17T20:09:23.050 に答える
2

問題の解決に役立つこのドキュメントを確認してください。次のコマンドオプションを使用することをお勧めします。

winhttpcertcfg -g -c LOCAL_MACHINE\My -s MyCertificate -a TESTUSER 
于 2010-11-17T15:33:25.123 に答える
0

匿名ユーザーにもアクセスを許可する必要がある場合があります。匿名アクセスを許可している場合、リクエストはネットワークサービスではなく匿名ユーザーとして実行されています。

于 2010-10-14T18:02:22.543 に答える