web-dev-qa-db-fra.com

"Une erreur interne a eu lieu." lors du chargement du fichier pfx avec X509Certificate2

J'essaie d'utiliser un certificat auto-signé (c #):

X509Certificate2 cert = new X509Certificate2(
    Server.MapPath("~/App_Data/myhost.pfx"), "pass");

sur un serveur d'hébergement Web partagé et j'ai eu une erreur:

System.Security.Cryptography.CryptographicException: An internal error occurred.

la trace de pile se termine par

System.Security.Cryptography.CryptographicException.
    ThrowCryptogaphicException(Int32 hr) +33
System.Security.Cryptography.X509Certificates.X509Utils.
    _LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, 
        Boolean persistKeySet, SafeCertContextHandle& pCertCtx) +0
System.Security.Cryptography.X509Certificates.X509Certificate.
    LoadCertificateFromFile(String fileName, Object password, 
        X509KeyStorageFlags keyStorageFlags) +237
System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(
    String fileName, String password) +131

Sur ma machine de développement, il se charge correctement. La raison pour laquelle je charge * .pfx n'est pas un fichier * .cer car j'ai besoin d'un accès par clé privée (le fichier cer se charge bien). J'ai fait pfx sur mon dev mochine comme ça:

makecert -r -n "CN=myhost.com, [email protected]" -sky exchange -b 01/01/2009
    -pe -sv myhost.pvk myhost.cer
<b>pvk2pfx</b> -pvk myhost.pvk -spc myhost.cer -pfx myhost.pfx -po pass</code>

J'utilise la version v5.131.3790.0 de makecert

76
tmp3128

Utilisez le magasin informatique local pour la clé privée:

X509Certificate2 cert = new X509Certificate2("myhost.pfx", "pass",
    X509KeyStorageFlags.MachineKeySet);

MachineKeySet est décrit comme "les clés privées sont stockées dans le magasin informatique local plutôt que dans le magasin utilisateur actuel". La valeur par défaut sans indicateur est de placer dans le magasin d'utilisateurs.

Même si vous lisez le certificat à partir du disque et le stockez dans un objet, les clés privées sont toujours stockées dans la base de données de clés du fournisseur de services cryptographiques de l'API cryptographique Microsoft. Sur le serveur d'hébergement, le processus ASP.NET n'est pas autorisé à accéder au magasin d'utilisateurs.

Une autre approche (selon certains commentaires ci-dessous) consiste à modifier l'identité IIS Configuration ou App Pool - qui fonctionne. Cependant, cela suppose qu'il existe un accès à ces éléments de configuration qui peuvent ne pas être le cas (par exemple dans un environnement d'hébergement partagé).

140
Randy Levy

J'ai essayé la solution de Randy de le changer en MachineKeySet, mais j'ai ensuite reçu le message d'erreur:

"clé non valide pour une utilisation dans l'état spécifié"

Donc, après un peu de recherche sur Google, j'ai trouvé un article qui a suggéré de le changer en:

var certificate = new X509Certificate2(certKeyFilePath, passCode, 
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet |       
X509KeyStorageFlags.PersistKeySet );

et cela a réglé mes problèmes.

Je n'ai pas encore essayé la suggestion de modifier le paramètre du pool d'applications dans la configuration IIS. Pour ce faire, accédez aux paramètres avancés du pool d'applications de votre site, puis définissez "charger le profil utilisateur" sur true. Lorsque ce paramètre est faux, les conteneurs de clés ne sont apparemment pas accessibles.

10
Myke Black