//cert is an EF Entity and
// cert.CertificatePKCS12 is a byte[] with the certificate.
var certificate = new X509Certificate(cert.CertificatePKCS12, "SomePassword");
Beim Laden eines Zertifikats aus unserer Datenbank auf unserem Staging-Server (Windows 2008 R2 / IIS7.5) wird folgende Ausnahme angezeigt:
System.Security.Cryptography.CryptographicException: An internal error occurred.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
HINWEIS: Dieses Problem tritt nicht lokal auf (Windows 7 / Casini).
Jeder Einblick wird sehr geschätzt.
c#
.net
x509certificate
lukiffer
quelle
quelle
byte[]
Daten liegt, die incert.CertificatePKCS12
. Ohne die Daten kann man nur den Grund der Ausnahme "Ein interner Fehler ist aufgetreten" erraten. Mein Vorschlag ist also, dass Sie das Testzertifikat erstellen, das in Ihrer Umgebung verwendet werden kann, um das Problem zu reproduzieren, es in der Datei speichern und den Link und das Kennwort (wie "SomePassword") zum Dekodieren des Zertifikats angeben. Nach Prüfung der Daten hat man viel mehr Chancen, die Resonanz zu finden und eine Lösung für Ihr Problem vorzuschlagen.cert.CertificatePKCS12
.Antworten:
Es stellt sich heraus, dass in der IIS-Anwendungspoolkonfiguration (Anwendungspools> Erweiterte Einstellungen) eine Einstellung zum Laden des Benutzerprofils für den Benutzer der Anwendungspoolidentität vorhanden ist. Bei false sind die Schlüsselcontainer nicht zugänglich.
Stellen Sie einfach die
Load User Profile
Option als einTrue
quelle
Wenn Sie in Visual Studio / Cassini ausgeführt werden, greift es höchstwahrscheinlich auf Ihren Benutzerzertifikatsspeicher zu, obwohl Sie ihn aus Bytes laden. Könnten Sie dies bitte versuchen und sehen, ob es Ihr Problem löst:
var certificate = new X509Certificate( cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet);
Dies führt dazu, dass IIS (das als ASP.NET-Benutzer ausgeführt wird, der wahrscheinlich keinen Zugriff auf einen Benutzerspeicher hat) den Computerspeicher verwendet.
Auf dieser Seite wird der Konstruktor ausführlicher erläutert, und auf dieser Seite wird die
X509KeyStorageFlags
Aufzählung erläutert .Bearbeiten: Basierend auf dem zweiten Link von cyphr scheint es eine gute Idee zu sein (wenn die vorherige Lösung nicht funktioniert), einige der
FlagsAttribute
Aufzählungswerte wie folgt zu kombinieren :var certificate = new X509Certificate( cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
Wenn Sie Zugriff haben, können Sie außerdem versuchen, die Einstellung für den Anwendungspool so zu ändern, dass LocalService verwendet wird (und anschließend den AppPool neu starten). Dies kann Ihre Berechtigungen auf ein angemessenes Niveau erhöhen, wenn dies das Problem ist.
Schließlich können Sie
File.WriteAllBytes
denCertificatePKCS12
Inhalt in eine pfx-Datei schreiben und prüfen, ob Sie ihn manuell über die Zertifikatkonsole unter MMC importieren können (Sie können ihn nach erfolgreichem Import löschen; dies dient nur zum Testen). Es kann sein, dass Ihre Daten munged werden oder das Passwort falsch ist.quelle
X509KeyStorageFlags.MachineKeySet
Flagge, sowie wenn alle drei das HinzufügenMachineKeySet
,PersistKeySet
undExportable
Flaggen.File.WriteAllBytes
um denCertificatePKCS12
Inhalt in eine pfx-Datei zu schreiben und zu prüfen, ob Sie ihn manuell über die Zertifikatkonsole unter MMC importieren können (Sie können ihn nach erfolgreichem Import löschen; dies dient nur zum Testen). Es kann sein, dass Ihre Daten munged werden oder das Passwort falsch ist.SignTool.exe
von Ihrem ASP.NET-Projekt aus aufrufen möchten, weiterhin 'LoadUserProfile' für das aktivieren müssenApplication Pool
. AndernfallsSignTool.exe
An internal error occurred
Verwenden Sie diesen Code:
certificate = new X509Certificate2(System.IO.File.ReadAllBytes(p12File) , p12FilePassword , X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
quelle
Ich hatte Probleme mit Windows 2012 Server R2, wo meine Anwendung keine Zertifikate für einen PFX auf die Festplatte laden konnte. Es würde gut funktionieren, wenn meine App als Administrator ausgeführt würde, und die Ausnahme lautete "Zugriff verweigert", sodass es sich um ein Berechtigungsproblem handeln musste. Ich habe einige der oben genannten Ratschläge ausprobiert, aber ich hatte immer noch das Problem. Ich fand, dass die Angabe der folgenden Flags als dritter Parameter des Zertifikatskonstruktors den Trick für mich tat:
quelle
Um Ihr Problem wirklich lösen zu können und nicht nur zu erraten, was es sein kann, muss man in der Lage sein , Ihr Problem zu reproduzieren . Wenn Sie keine Test-PFX-Datei mit demselben Problem bereitstellen können, müssen Sie das Problem selbst untersuchen. Die erste wichtige Frage lautet: Liegt der Ursprung der Ausnahme "Ein interner Fehler ist aufgetreten" im privaten Schlüsselteil des PKCS12 oder im öffentlichen Teil des Zertifikats selbst?
Daher würde ich Ihnen empfehlen, dasselbe Experiment mit demselben Zertifikat zu wiederholen, das ohne privaten Schlüssel exportiert wurde (wie die .CER-Datei):
var certificate = new X509Certificate(cert.CertificateCER);
oder
var certificate = new X509Certificate.CreateFromCertFile("My.cer");
Es kann hilfreich sein, zu überprüfen, ob der Ursprung Ihres Problems der private Schlüssel oder einige Eigenschaften des Zertifikats sind.
Wenn Sie Probleme mit der CER-Datei haben, können Sie den Link zur Datei sicher veröffentlichen, da er nur öffentliche Informationen enthält. Alternativ können Sie zumindest ausführen
CertUtil.exe -dump -v "My.cer"
oder
CertUtil.exe -dump -v -privatekey -p SomePassword "My.pfx"
(Sie können auch einige andere Optionen verwenden) und einige Teile der Ausgabe veröffentlichen (z. B. Eigenschaften des privaten Schlüssels ohne das PRIVATEKEYBLOB selbst).
quelle
Eine Alternative zum Ändern des Ladebenutzerprofils besteht darin, dass der Anwendungspool die Netzwerkdienstidentität verwendet .
Siehe auch Was passiert genau, wenn ich LoadUserProfile des IIS-Pools einstelle?
quelle
Sie müssen ein CER-Zertifikat in den Keystore Ihres lokalen Computers importieren. Sie müssen Ihr .p12-Zertifikat nicht importieren. Verwenden Sie stattdessen das zweite von Apple für Ihr Konto ausgestellte Zertifikat. Ich denke, es muss ein gültiges Zertifikatspaar sein (eines im Dateisystem, das zweite im Keystore). Sie müssen natürlich alle 3 Flags in dll setzen.
quelle
In einer Anwendung, in der IIS 10 ausgeführt wird, konnte ich den Fehler beim Verweigern des Zugriffs beheben, indem ich die LocalSystem-Identität für den App-Pool mit dem folgenden Code verwendete:
new X509Certificate2(certificateBinaryData, "password" , X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
Das Aktivieren des Ladeprofils für Benutzer hat bei mir nicht funktioniert, und obwohl es viele Vorschläge dazu gab, wurde nicht angegeben, dass die Einstellung für "Benutzerprofil laden" auf "True" nur für Benutzerkonten funktioniert und nicht:
quelle
Der folgende Code hilft Ihnen dabei, mithilfe der Hüpfburgbibliothek einen Algorithmus zu generieren:
private static ECDsa GetEllipticCurveAlgorithm(string privateKey) { var keyParams = (ECPrivateKeyParameters)PrivateKeyFactory .CreateKey(Convert.FromBase64String(privateKey)); var normalizedECPoint = keyParams.Parameters.G.Multiply(keyParams.D).Normalize(); return ECDsa.Create(new ECParameters { Curve = ECCurve.CreateFromValue(keyParams.PublicKeyParamSet.Id), D = keyParams.D.ToByteArrayUnsigned(), Q = { X = normalizedECPoint.XCoord.GetEncoded(), Y = normalizedECPoint.YCoord.GetEncoded() } }); }
und generieren Sie das Token folgendermaßen:
var signatureAlgorithm = GetEllipticCurveAlgorithm(privateKey); ECDsaSecurityKey eCDsaSecurityKey = new ECDsaSecurityKey(signatureAlgorithm) { KeyId = settings.Apple.KeyId }; var handler = new JwtSecurityTokenHandler(); var token = handler.CreateJwtSecurityToken( issuer: iss, audience: AUD, subject: new ClaimsIdentity(new List<Claim> { new Claim("sub", sub) }), expires: DateTime.UtcNow.AddMinutes(5), issuedAt: DateTime.UtcNow, notBefore: DateTime.UtcNow, signingCredentials: new SigningCredentials(eCDsaSecurityKey, SecurityAlgorithms.EcdsaSha256));
quelle