79 votes

Exception constructeur X509Certificate

 //cert is an EF Entity and 
//    cert.CertificatePKCS12 is a byte[] with the certificate.

var certificate = new X509Certificate(cert.CertificatePKCS12, "SomePassword");
 

Lors du chargement d'un certificat depuis notre base de données, sur notre serveur de transfert (Windows 2008 R2 / IIS7.5), nous obtenons cette exception:

 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)
 

REMARQUE: ce problème ne se produit pas localement (Windows 7 / Casini).

Tout conseil est grandement apprécié.

132voto

lukiffer Points 4944

Il s'avère qu'il existe un paramètre dans la configuration du pool d'applications IIS (Pools d'applications> Paramètres avancés) pour charger le profil utilisateur de l'utilisateur d'identité du pool d'applications. Lorsqu'il est défini sur false, les conteneurs de clés ne sont pas accessibles.

67voto

Chris Benard Points 1430

Plus que probablement, lorsque vous exécutez à partir de Visual Studio/Cassini, c'est accéder à votre utilisateur de magasin de certificats, même si vous êtes en train de charger à partir d'octets. Pourriez-vous s'il vous plaît essayer cela et voir si cela résout votre problème:

var certificate = new X509Certificate(
    cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet);

Ce sera la cause de IIS (qui s'exécute en tant que ASP.NET l'utilisateur qui probablement n'ont pas accès à un magasin d'utilisateur) pour utiliser le magasin de l'ordinateur.

Cette page explique le constructeur dans le détail, et cette page explique l' X509KeyStorageFlags énumération.

Edit: Basé sur le deuxième lien de cyphr, on dirait qu'il pourrait être une bonne idée (si la solution précédente ne fonctionne pas), de combiner certains de l' FlagsAttribute des valeurs d'une énumération comme suit:

var certificate = new X509Certificate(
    cert.CertificatePKCS12, "SomePassword",
    X509KeyStorageFlags.MachineKeySet
    | X509KeyStorageFlags.PersistKeySet
    | X509KeyStorageFlags.Exportable);

En outre, si vous y avez accès, vous pouvez essayer de changer votre Application Piscine à usage Local (et puis redémarrez le pool d'applications). Cela peut élever vos autorisations à un niveau approprié, si c'est bien le problème.

Enfin, vous pouvez utiliser File.WriteAllBytes d'écrire l' CertificatePKCS12 le contenu d'un fichier pfx et voir si vous pouvez l'importer manuellement à l'aide du certificat de la console en vertu de la console MMC (vous pouvez supprimer après le succès de l'importation; c'est juste pour tester). Il se pourrait que vos données sont munged, ou le mot de passe est incorrect.

34voto

Francisco Points 81

Utilisez ce code:

 certificate = new X509Certificate2(System.IO.File.ReadAllBytes(p12File)
                                   , p12FilePassword
                                   , X509KeyStorageFlags.MachineKeySet |
                                     X509KeyStorageFlags.PersistKeySet | 
                                     X509KeyStorageFlags.Exportable);
 

2voto

Oleg Points 136406

Pour être vraiment en mesure de résoudre votre problème et pas seulement deviner, que peut-il être, il faut être en mesure de reproduire votre problème. Si vous ne pouvez pas fournir de test de fichier PFX qui ont le même problème que vous avez à examiner le problème vous-même. La première question importante est: sont à l'origine de l'exception "Une erreur interne s'est produite" par la clé privée d'une partie de la PKCS12 ou dans la partie publique du certificat lui-même?

Donc, je vous recommande d'essayer de répéter la même expérience avec le même certificat, exportés sans clé privée (comme .Fichier CER):

var certificate = new X509Certificate(cert.CertificateCER);

ou

var certificate = new X509Certificate.CreateFromCertFile("My.cer");

Il pourrait aider à vérifier si l'origine de votre problème est la clé privée ou certaines propriétés du certificat.

Si vous avez un problème avec le fichier CER vous pouvez sûre de poster le lien vers le fichier parce qu'il l'ait publique d'information seulement. Sinon, vous pouvez au moins exécuter

CertUtil.exe -dump -v "My.cer"

ou

CertUtil.exe -dump -v -privatekey -p SomePassword "My.pfx"

(vous pouvez utiliser d'autres options aussi) et après quelques parties de la sortie (par exemple les propriétés de la clé privée sans le PRIVATEKEYBLOB lui-même).

2voto

Une alternative à la modification du profil utilisateur de charge consiste à faire en sorte que le pool d'applications utilise l'identité de service réseau .

Voir aussi Que se passe-t-il exactement lorsque je définis LoadUserProfile du pool IIS?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X