Windowsの .rdp ファイルを開くと、「このリモート接続の発行元を確認する」というセキュリティ警告が表示されることがある。
今回は、自分で作成したRDPファイルを署名するための自己署名証明書をPowerShellで作成し、公開証明書を .cer、秘密鍵を含むバックアップを .pfx として保存する手順を残す。
手順が長いため、記事を次の2つに分けた。
- この記事:RDP署名用証明書の作成とバックアップ
- 1-2. RDP署名:
rdpsign、グループポリシー、ドラッグ&ドロップ用BAT
RDPファイルの署名とRDPサーバーのTLS証明書は別物
この記事で作るのは、.rdp ファイルそのものの発行元を示すための署名用証明書である。
「リモート コンピューターのIDを識別できません」などの警告で使われる、RDPサーバー側のTLS証明書とは役割が異なる。今回の証明書を作成しても、サーバー証明書に関する警告は解消されない。
作業ディレクトリを作る
この記事では、公開証明書と後編で作るBATを C:\RDPs に置く。
PowerShellを開き、次のコマンドを実行する。
New-Item -ItemType Directory -Path 'C:\RDPs' -Force
最終的には次の構成になる。
C:\RDPs\
├─ MyRdpPublisher.cer
└─ sign_rdp_dragdrop.bat
PFXバックアップは秘密鍵を含むため、このディレクトリへ常置せず、安全な別の場所で保管する。
RDP署名用の自己署名証明書を作成する
Windows PowerShellで次のコマンドを実行する。
$params = @{
Type = 'CodeSigningCert'
Subject = 'CN=My RDP Publisher'
FriendlyName = 'My RDP Publisher'
CertStoreLocation = 'Cert:\CurrentUser\My'
KeyAlgorithm = 'RSA'
KeyLength = 2048
HashAlgorithm = 'SHA256'
KeyExportPolicy = 'Exportable'
}
$cert = New-SelfSignedCertificate @params
作成された証明書オブジェクトは $cert に入る。
Microsoft Learnでは、New-SelfSignedCertificate の Type に CodeSigningCert、鍵用途に DigitalSignature、鍵アルゴリズムにRSAまたはECDSAを指定できる。今回はRDPファイルの発行元署名という用途を明確にするため CodeSigningCert を使い、互換性を考えてRSA 2048 bitとした。
CodeSigningCert が署名用途とCode Signing EKUを設定するため、同じ内容を KeyUsage や TextExtension で重複指定していない。KeyAlgorithm と KeyLength は rdpsign 固有の必須指定としてMicrosoftが案内しているわけではなく、作成条件を固定するための選択である。
HashAlgorithm = 'SHA256' は、自己署名証明書自体を署名するときのハッシュアルゴリズムを指定する。後編で rdpsign /sha256 に渡す証明書の拇印とは別の項目である。
KeyExportPolicy = 'Exportable' は、Windows再インストールや別PCへの移行に備えて秘密鍵をPFXへ書き出せるようにするために指定した。バックアップが不要で秘密鍵をエクスポートさせたくない場合は、運用方針を決めてから変更する。
NotAfter は指定していない。Microsoft Learnによると、この場合の有効期限は作成から1年である。期限を変更する場合は、目的に合う期間を決めて -NotAfter を明示する。
証明書を確認する
作成直後であれば、次のコマンドで必要な項目を確認できる。
$cert | Select-Object Subject, Thumbprint, HasPrivateKey, NotBefore, NotAfter
確認する項目は次のとおり。
SubjectがCN=My RDP PublisherThumbprintが表示されるHasPrivateKeyがTrueNotBeforeとNotAfterが想定した有効期間
特に、HasPrivateKey = True であることを確認する。秘密鍵がなければ .rdp ファイルへ署名できない。
PowerShellを開き直したあとに確認する場合は、Subjectで絞り込む。
$cert = Get-ChildItem 'Cert:\CurrentUser\My' |
Where-Object Subject -eq 'CN=My RDP Publisher' |
Sort-Object NotBefore -Descending |
Select-Object -First 1
$cert | Select-Object Subject, Thumbprint, HasPrivateKey, NotBefore, NotAfter
同名の証明書を複数作成している場合があるため、一覧の先頭を無条件に使わず、有効期間と拇印も確認する。
Code Signing EKUは次のコマンドで確認できる。
$cert.EnhancedKeyUsageList | Select-Object FriendlyName, ObjectId
GUIで確認する場合は certmgr.msc を起動し、個人 → 証明書から My RDP Publisher を開く。「全般」タブで「この証明書に対応する秘密キーを持っています」と表示されることも確認する。
公開証明書をCERへエクスポートする
次のコマンドで公開証明書を保存する。
Export-Certificate `
-Cert $cert `
-FilePath 'C:\RDPs\MyRdpPublisher.cer'
Microsoft Learnの仕様どおり、Export-Certificate で出力した単一の .cer ファイルには秘密鍵が含まれない。
ファイルを確認する。
Get-Item 'C:\RDPs\MyRdpPublisher.cer'
CERだけでは署名できない理由
MyRdpPublisher.cer は公開証明書であり、通常は秘密鍵を含まない。このファイルだけを別PCへコピーしても、そのPCでは同じ発行元として .rdp ファイルを署名できない。
rdpsign が実際の署名に使うのは、Windowsの証明書ストアに登録された次の証明書である。
.cerと同じ証明書- 秘密鍵付き
CurrentUser\MyまたはLocalMachine\Myに存在する
後編のBATは .cer から拇印を読み取り、「どの証明書を使うのか」を識別する。しかし、署名そのものには証明書ストア内の秘密鍵が必要になる。
MyRdpPublisher.cer
│
└─ 公開情報と拇印を取得
Cert:\CurrentUser\My\<Thumbprint>
│
└─ 秘密鍵を使って実際に署名
秘密鍵をPFXとしてバックアップする
Windowsを再インストールすると、証明書ストア内の秘密鍵も失われる。今後も同じ発行元として署名するには、秘密鍵を含むPFXをバックアップしておく。
パスワードはコマンドやスクリプトに直接書かず、実行時に入力する。
$pfxPassword = Read-Host 'PFX password' -AsSecureString
Export-PfxCertificate `
-Cert $cert `
-FilePath 'D:\SecureBackup\MyRdpPublisher-backup.pfx' `
-Password $pfxPassword
D:\SecureBackup は例なので、実際にはアクセス制御された安全な保存先へ変更する。PFXとパスワードを同じ場所へ平文で保存しない。
復元するときは、PFXを CurrentUser\My へインポートする。
$pfxPassword = Read-Host 'PFX password' -AsSecureString
Import-PfxCertificate `
-FilePath 'D:\SecureBackup\MyRdpPublisher-backup.pfx' `
-CertStoreLocation 'Cert:\CurrentUser\My' `
-Password $pfxPassword
インポート後は、もう一度 HasPrivateKey = True を確認する。
秘密鍵の管理
秘密鍵を持つ人は、My RDP Publisher と同じ発行元としてRDPファイルへ署名できる。PFXは公開用の .cer やBATとは分けて保管し、第三者へ渡さない。
自己署名証明書は、自分で管理するPCや検証環境で使うためのものとする。組織全体へRDPファイルを配布する場合は、組織の証明書ポリシーに従い、管理された発行元証明書を利用する。
次の手順
証明書と公開用 .cer を用意できたら、次の記事へ進む。
後編では、rdpsign による署名、信頼済みRDP発行元のグループポリシー、複数の .rdp ファイルをドラッグ&ドロップで再署名するBATを設定する。