Haftungsausschluss: Fragen mit Titeln wie dieser sind üblich, aber keine Antwort hat mir eine Lösung geliefert, also muss ich sie trotzdem fragen (mit einem neuen Parametersatz).Konnte keinen sicheren Kanal für SSL/TLS mit der Autorität 'site.com' aufbauen
Problem
Ein Webservice-Client-Endpunkt in web.config wie folgt erklärt:
<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>
Die Zertifikate (Client und Server-Zertifikat) werden mit der App "Zertifikate verwalten Computer" installiert. Sie werden in einer CER-Datei (Serverzertifikat) bzw. einer PFX-Datei (Clientzertifikat) gespeichert. Sie werden beide in "Vertrauenswürdige Stammzertifizierungsstellen" gespeichert.
Erfolg
den Client Ausführen des Visual Studio Debug-Webserver (IIS Express) verwendet, ist erfolgreich.
Failure
Allerdings, wenn ich versuche, es in IIS zu laufen, erhalte ich die Fehlermeldung
nicht sicheren Kanal mit Autorität für SSL/TLS etablieren kann 'site.com'
Problemlösung Methode
ich habe versucht, eine Web-aPI-Funktion zu erstellen, die mich wissen lässt, wenn der Server fest die fraglichen Zertifikate. Es tut. Der Code sieht aus wie
[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;
}
}
}
}
Auch wenn ich dies auf IIS leite ich eine Ausgabe wie diese zu erhalten (mit console.log in Chrom):
So sind die certs sind deutlich sichtbar an den IIS, obwohl sie in "Vertrauenswürdige Stammzertifizierungsstellen" gespeichert sind. Die einzige Möglichkeit, Daten zu verfallen, die abgerufen werden könnten, ist die Verwendung des Geschäfts.
Wie füge ich Rechte zum privaten Schlüssel zum APP-Pool Pseudobenutzer, der certlm.msc verwendet? Ich habe das Problem jetzt mit icacls.exe gelöst, einem Tool, das ich herunterladen musste. Wenn ich stattdessen certlm.msc verwenden kann, kann ich den Workflow für zukünftige Anwendungen vereinfachen. https://github.com/EricHerlitz/Mobile-BankId-.NET-Example/issues/5 –
Rechtsklick auf Zertifikat in certlm.msc Werkzeug, dann 'Alle Aufgaben-> Private Schlüssel verwalten ...'. Es öffnet sich ein Fenster wie wenn Sie Rechte an Dateien vergeben. Setzen Sie 'IIS APPPOOL \ name_of_the_apppool_your_app_runs_under' als Benutzer und klicken Sie auf OK. – pepo