Windows での証明書管理について、多くの人がかなり混乱しているようです。特に、証明書が実際にどこに保存されているのか、あるいは手動でどのように抽出するのかを把握しようとすると、混乱してしまいます。 や のようなグラフィカルなMMCスナップインは確かに便利ですが、論理的なビューしか表示しません。実際には、暗号化関連の情報はレジストリやファイルシステムに分散しており、どこを調べればよいのか必ずしも明確ではありません。また、トラブルシューティングやオフラインリカバリを行う場合、レジストリから直接証明書を抽出できれば、状況は改善される可能性があります。ただし、秘密鍵が暗号化されていたりディスクに保存されていたりする場合は、すぐに混乱してしまう可能性があります。この記事では、これらの保存場所について説明し、実用的なコマンドやスクリプトをいくつか紹介します。certlm.msccertmgr.msc
Windows での証明書の保存方法を理解する方法
論理証明書ストアの場所と物理証明書ストアの場所
まず、Windowsはすべてを1か所にまとめて保存するわけではありません。公開鍵は多くの場合レジストリに保存されますが、秘密鍵は暗号化されてディスクに保存されます。 ではcertmgr.msc論理的なビューを確認できます。表示される証明書は、実際の鍵データではなく、単なるポインタのようなものになります。証明書コンソールで「表示」→「オプション」に移動し、「物理証明書ストア」を有効にすると、鍵が保存されている実際の保存場所(レジストリ、ローカルファイル、スマートカードなど)ごとにグループ化された保存場所が表示されます。
証明書の主なレジストリ パス:
- ユーザー証明書:
HKCU\SOFTWARE\Microsoft\SystemCertificates— ユーザーごとに保存され、公開鍵が含まれます。 - グループポリシーで展開された証明書:
HKCU\SOFTWARE\Policies\Microsoft\SystemCertificates - マシン証明書:
HKLM\SOFTWARE\Microsoft\SystemCertificates - サービスとエンタープライズCA:
HKLM\SOFTWARE\Microsoft\Cryptography\ServicesおよびHKLM\SOFTWARE\Microsoft\EnterpriseCertificates
秘密鍵はレジストリに直接保存されません。代わりに、その参照は次のような場所に保存されます。
%APPDATA%\Microsoft\SystemCertificates: ユーザー証明書とポインタ用%APPDATA%\Microsoft\Crypto: ユーザーの秘密鍵コンテナ%ProgramData%\Microsoft\Crypto: マシン全体の秘密鍵ストレージ
もちろん、Windowsはこれらの秘密鍵をDPAPIで暗号化し、ユーザーアカウントのパスワードに紐付けています。そのため、たとえ誰かがレジストリをダンプしたとしても、ユーザーのトークンやパスワードにアクセスできない限り、秘密鍵を簡単に入手することはできません。
PowerShellとcertutilを使って証明書にアクセスする方法
稼働中のシステムで証明書を操作したり一覧表示したりするには、PowerShellのCert Providerが役立ちます。設定によっては、かなり単純な操作で動作します。ちょっと奇妙ですが、まあいいでしょう。例えば、マシンストアに移動するには次のようにします。
cd Cert:\LocalMachine\My
そこにあるすべての証明書を一覧表示するには、次のようにします。
Get-ChildItem
あるいは、コマンドラインを使いたい場合は、certutilこちらが良い代替手段です。例えば、「MY」(個人用)ストアを一覧表示するには、次のようにします。
certutil -store MY
レジストリから証明書を直接抽出する
さて、ここで一部の人がつまずく部分があります。証明書は に保存されますHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\MY。 内では、各証明書のキー名の一部として拇印が含まれ、実際の証明書データはレジストリ値(通常は )にBLOBBlobとして保存されます。データは DER エンコーディングで保存されており、人間が読める形式ではありませんが、変換することは可能です。PowerShell でスクリプトを記述してこのデータを抽出し、適切なX509Certificate2オブジェクトに変換してから、エクスポートしたり、さらに詳しく調べたりすることができます。
$regPath = "HKLM:\SOFTWARE\Microsoft\SystemCertificates\MY\Certificates\" $blob = (Get-ItemProperty -Path $regPath).Blob $cert = New-Object System. Security. Cryptography. X509Certificates. X509Certificate2 -ArgumentList (, $blob) $cert | Format-List Subject, Issuer, NotBefore, NotAfter, Thumbprint
証明書オブジェクトを取得したら、それを CER ファイルとしてエクスポートするのは簡単です。
$certBytes = $cert. Export([System. Security. Cryptography. X509Certificates. X509ContentType]::Cert) [System. IO. File]::WriteAllBytes("C:\path\to\exported_cert.cer", $certBytes)
このトリックは、オフラインイメージから証明書を復元したり、壊れた証明書ストアのトラブルシューティングをしたりする場合に非常に便利です。少し面倒ですが、不可能ではありません。
理由は定かではありませんが、一部のマシンでは最初はうまく動作するものの、その後はうまく動作しなくなるため、試行錯誤が必要になる可能性があります。それでも、レジストリハイブを手動で力ずくで調べるよりはましです。