1. ホーム
  2. c#

「X509Certificate2 で pfx ファイルを読み込むと「内部エラーが発生しました。

2023-07-28 12:27:21

質問

自己署名証明書を使おうとしています(C#)。

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

を共有のウェブホスティングサーバーで実行すると、エラーが発生しました。

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

でスタックトレースが終了します。

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

私の開発マシンでは、読み込みはOKです。 cerファイルではなく、*.pfxを読み込むのは、秘密鍵のアクセスが必要だからです(cerファイルは問題なく読み込めます)。 私の開発機では、このようにpfxを作成しました。

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>

私はmakecertのバージョンv5.131.3790.0を使用しています。

どのように解決するのですか?

秘密鍵は、ローカルコンピュータのストアを使用します。

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

MachineKeySet は、"秘密鍵は現在のユーザストアではなく、ローカルコンピュータストアに保存されます"と記述されています。フラグなしのデフォルトは、ユーザー ストアに配置されます。

ディスクから証明書を読み込んでオブジェクトに保存していても、秘密鍵は Microsoft Cryptographic API Cryptographic Service Provider 鍵データベースに保存されます。ホスティングサーバー上では、ASP.NET プロセスはユーザー ストアにアクセスする権限を持っていません。

別のアプローチ (以下のいくつかのコメントによる) は、IIS 構成または App Pool ID を変更することで、これは動作します。 しかし、これは、これらの構成項目へのアクセスがあることを前提としており、そうでない場合もあります (たとえば、共有ホスティング環境において)。