2017-11-08 3 views
0

免責事項:このようなタイトルの質問は一般的ですが、解決策は私には解決策を提供していないので、パラメータのセット)。権限 'site.com'を持つSSL/TLSのセキュリティで保護されたチャネルを確立できませんでした

Webサービスクライアントエンドポイントは、次のようにweb.configファイルで宣言されている

問題:

<behaviors> 
    <endpointBehaviors> 
    <behavior name="bankid"> 
     <clientCredentials> 
     <clientCertificate findValue="FP Testcert 2" 
      storeLocation="LocalMachine" 
      storeName="Root" 
      x509FindType="FindBySubjectName"/> 
     <serviceCertificate> 
      <defaultCertificate findValue="Test BankID SSL Root CA v1 Test" 
      storeLocation="LocalMachine" 
      storeName="Root" 
      x509FindType="FindBySubjectName"/> 
     <authentication certificateValidationMode="None" 
      revocationMode="NoCheck" 
      trustedStoreLocation="LocalMachine"/> 
     </serviceCertificate> 
     </clientCredentials> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 

証明書(クライアントとサーバ証明書)「コンピュータ証明書の管理」アプリを使用してインストールされています。 .cerファイル(サーバー証明書)と.pfxファイル(クライアント証明書)にそれぞれ格納されます。両方とも「信頼されたルート証明機関」に格納されています。 Visual StudioのデバッグWebサーバ(IIS Expressを)使用してクライアントを実行して成功

成功です。私はIISでそれを実行しようとすると

失敗

はしかし、私はエラーメッセージ

が権限 でSSL/TLSの安全なチャネルを確立できませんでした 'site.com'

を取得します

私は、サーバーが見つかった場合、私は知ることができますウェブAPI関数を作成しようとしました

問題解決方法問題の証明書。します。コードは、私はIIS上でこれを実行している場合でも、私は(クロームではconsole.logを使用して)このような出力を得る

[HttpGet] 
[Route("Debug/certs")] 
public CertsOutput certs() 
{ 
    var certStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine); 

    certStore.Open(OpenFlags.ReadOnly); 

    var config = System.Web.Configuration.WebConfigurationManager 
     .OpenWebConfiguration("~"); 
    var group = ServiceModelSectionGroup.GetSectionGroup(config); 
    var endPointBehaviors = group.Behaviors.EndpointBehaviors; 
    var endpointBehavior = endPointBehaviors[0]; 

    var ClientCredential = (ClientCredentialsElement) endpointBehavior[0]; 

    var clientCert = ClientCredential.ClientCertificate; 
    var serverCert = ClientCredential.ServiceCertificate.DefaultCertificate; 

    var result = new CertsOutput 
    { 
     clientCert = new CertsOutput.Cert 
     { 
      FindValue = clientCert.FindValue, 
      StoreName = clientCert.StoreName.ToString(), 
      StoreLocation = clientCert.StoreLocation.ToString(), 
      FindType = clientCert.X509FindType.ToString() 
     }, 

     serverCert = new CertsOutput.Cert 
     { 
      FindValue = serverCert.FindValue, 
      StoreName = serverCert.StoreName.ToString(), 
      StoreLocation = serverCert.StoreLocation.ToString(), 
      FindType = serverCert.X509FindType.ToString() 
     } 
    }; 

    return result; 
} 

public class CertsOutput 
{ 
    public Cert clientCert { get; set; } 
    public Cert serverCert { get; set; } 

    public class Cert 
    { 
     public string FindValue { get; set; } 
     public string StoreName { get; set; } 
     public string StoreLocation { get; set; } 
     public string FindType { get; set; } 

     public string Expiration => Certificate?.GetExpirationDateString() 
      ?? "Cant find cert"; 

     X509Certificate _certificate = null; 
     private X509Certificate Certificate 
     { 
      get 
      { 
       if (_certificate != null) 
        return _certificate; 

       StoreName storeNameEnum; 
       switch(StoreName) 
       { 
        case "My": 
         storeNameEnum = System_StoreName.My; 
         break; 
        case "Root": 
         storeNameEnum = System_StoreName.Root; 
         break; 
        default: 
         throw new Exception("Unknown store name: " + StoreName); 
       } 

       StoreLocation storeLocationEnum; 
       switch(StoreLocation) 
       { 
        case "LocalMachine": 
         storeLocationEnum = System_StoreLocation.LocalMachine; 
         break; 
        case "CurrentUser": 
         storeLocationEnum = System_StoreLocation.CurrentUser; 
         break; 
        default: 
         throw new Exception("Unknown store location: " + StoreLocation); 
       } 

       var certStore = new X509Store(storeNameEnum, storeLocationEnum); 

       certStore.Open(OpenFlags.ReadOnly); 

       var certCollection = certStore.Certificates.Find 
        (X509FindType.FindBySubjectName, FindValue, validOnly:false); 

       certStore.Close(); 

       var result = certCollection[0]; 
       _certificate = result; 

       return result; 
      } 
     } 
    } 
} 

次のようになります。

output revealing that the IIS actually can use the certificates

だから、本命ははっきりと見えます「信頼されたルート証明機関」に格納されていますが、IISに送信します。期限切れの日付を取得できる唯一の方法は、ストアを使用することです。

答えて

1

CAPI2ログイベントログを有効にすると、なぜCould not create SSL/TLS secure channel. CAPI2ログが既定で無効になっているのかがわかります。有効にすると、再度要求を実行しようとします。原因に関する有用な情報を含むエラーイベントがいくつかあるはずです。

CAPI2 event log

私もチェックし(そしておそらく変更)いくつかのものです:IEで

  • オープンWCFエンドポイントとサイトがISに信頼されているかどうかを確認。理由を見つけられない場合。これが最初にやるべきことです。
  • クライアント証明書(pfx)はLocalMachine/My(個人用)ストアに配置する必要があります。ルートCA証明書は、信頼されたルート証明機関ストアに置かれている必要があります。中間CA証明書ストアに中間のCA証明書が格納されている必要があります。
  • WCFクライアントが実行されているIISアプリケーションプールに秘密キーを割り当てる必要があります。それはcertlm.mscツールを使用して行うことができます。
  • Web APIメソッドで秘密キーが使用可能であるかどうかを確認します。だからPrivateKeyのプロパティをチェックして、それを使ってhello worldデータに署名してください。
+0

certlm.mscを使用してアプリケーションプールの疑似ユーザに秘密鍵の権限を追加するにはどうすればよいですか?私は今ダウンロードしなければならなかったicacls.exeを使って問題を解決しました。代わりにcertlm.mscを使用すれば、将来のアプリケーションのワークフローを簡素化できます。 https://github.com/EricHerlitz/Mobile-BankId-.NET-Example/issues/5 –

+0

certlm.mscツールの証明書を右クリックしてから、「すべてのタスク - >秘密鍵を管理...」をクリックします。ファイルに権利を与えるときのようなウィンドウが開きます。 'IIS APPPOOL \ name_of_the_apppool_your_app_runs_under'をユーザーとして入力し、[OK]をクリックします。 – pepo

関連する問題

 関連する問題