2017-11-08 4 views
0

면책 조항 :이 같은 제목의 질문은 일반적인 내용이지만 답변이 나와 해결책이 없었으므로 어쨌든 물어볼 필요가 있습니다 매개 변수 세트).'site.com'권한으로 SSL/TLS에 대한 보안 채널을 설정할 수 없음

웹 서비스 클라이언트 엔드 포인트는 다음과 같이의 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 파일 (클라이언트 인증서)에 각각 저장됩니다. 둘 모두 "신뢰할 수있는 루트 인증 기관"에 저장됩니다. 비주얼 스튜디오의 디버그 웹 서버 (IIS 익스프레스)를 사용하여 클라이언트를 실행 성공

성공입니다. 내가 IIS에서 실행하려고 할 때

는 실패

그러나, 나는 오류 메시지가 얻을

권한과 SSL/TLS에 대한 보안 채널을 설정할 수 없습니다 'site.com'

나는 서버가 발견되면 알려 수있는 웹 API 함수를 만들려고 한

문제 해결 방법 문제의 증명서. 그렇습니다.

output revealing that the IIS actually can use the certificates

는 그래서 인증서 표시가 명확하게 볼 수 있습니다 : 코드는 내가 IIS에서이 작업을 실행하고 있더라도

[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; 
      } 
     } 
    } 
} 

처럼, 나는 (크롬에서 CONSOLE.LOG 사용)과 같은 출력을 얻을 보인다 IIS가 "신뢰할 수있는 루트 인증 기관"에 저장되지만 만료 날짜를 검색 할 수있는 유일한 방법은 상점을 사용하는 것입니다.

답변

1

CAPI2 로그인 이벤트 로그를 사용하면 Could not create SSL/TLS secure channel. CAPI2 로그가 기본적으로 비활성화되어있는 이유를 알 수 있습니다. 사용하도록 설정하면 요청을 다시 시도하십시오. 원인에 대한 유용한 정보가 포함 된 오류 이벤트가 있어야합니다.

CAPI2 event log

나는 또한 확인 (아마 변경) 할 몇 가지 :

  • 열기 WCF의 IE에서 엔드 포인트와 사이트가 IS 신뢰되어 있는지 확인합니다. 이유를 모르겠다면. 이것이 당신이해야 할 첫 번째 일입니다.
  • 클라이언트 인증서 (pfx)는 LocalMachine/My (개인) 상점에 저장해야합니다. 루트 CA 인증서는 신뢰할 수있는 루트 인증 기관 저장소에 있어야하며 중급 CA 인증서는 중간 인증 기관 저장소에 저장해야합니다.
  • WCF 클라이언트가 실행되는 IIS 응용 프로그램 풀에 개인 키에 대한 권한을 부여해야합니다. certlm.msc 도구를 사용하여 수행 할 수 있습니다.
  • 웹 API 방법에서 개인 키가 사용 가능한지 확인하십시오. 그래서 PrivateKey 속성을 확인하고 그와 같은 세계 데이터에 서명하십시오.
+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'을 사용자로 입력하고 확인을 클릭하십시오. – pepo

관련 문제