初めに
最近よくある相談事に「認証情報やパスワードをスクリプトに入れたくないのだけどどうすればいい?」があります。
Azure なら KeyVault を使ったり、マネージドIDを使ってそもそもパスワードを使わない運用にしたりします。
では端末だけで実行するならどうするか、というお話です。
この方法の特徴
- 暗号化を行ったコンピューター上で、その暗号化を実行したユーザーだけが復号できます
- 異なる端末/ユーザーに配布する場合、そのユーザー・環境ごとに暗号化したファイルや文字列が必要です
SecureStringを使う
暗号化した文字列を Read-Host と ConvertFrom-SecureString を使って作ることができます。
# 出力先
$OutFilePath = "c:\temp\encriptText.txt"
# 暗号化文字列を作る(入力する場合)
$SecureString = Read-Host "EnterPassword" -AsSecureString
# テキストファイルを暗号化する場合
# Get-Content $InputFilePath | ConvertTo-SecureString -AsPlainText -Force
# パスワードをDPAPIで暗号化
$EncryptedString = ConvertFrom-SecureString -SecureString $SecureString
# ファイルに書き出し
$EncryptedString | Out-File $OutFilePath
# 暗号文
$EncryptedFilePath = "c:\temp\encriptText.txt"
$EncryptedString = Get-Content -LiteralPath $EncryptedFilePath
$SecureString = ConvertTo-SecureString -String $EncryptedString
# コード内で平文が必要ならこれで変換
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString)
$plainText = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($BSTR)
共用PCや本番環境で
$SecureString = ConvertTo-SecureString 'hogehoge' -AsPlainText -Force
とかのコマンドを実行しないようにしましょう。
この例だと平文 'hogehoge' が履歴に残ります。
これで暗号化した文字列は、これを実行したユーザーがこのコンピューター上で実行するときに限り展開できるので、スクリプトと暗号化文字列を持ち出されても多少は安心。この文字列を別ファイルにしたり、ヒアストリングでスクリプトに埋め込んでください。
キーを指定しない場合には、Windows データ保護 API (DPAPI) が使用されて標準文字列の表現が暗号化されます。
.NET では、データ保護 API (DPAPI) へのアクセスを提供しています。これを使用すると、現在のユーザー アカウントまたはコンピューターからの情報を使用してデータを暗号化できます。
ユーザーと実行ユーザーを分離する
さらに強度を上げるならタスクスケジューラーを使います。
こちらのコラム紹介しているような方法で、スクリプトの恩恵を受けるユーザーと、スクリプトを実行するジョブ用のユーザアカウントを分離します。
PowerShellコラム:別のユーザーで処理を実行する 1
PowerShellコラム:別のユーザーで処理を実行する 2
コラムの1は、エンドユーザーがタスクスケジューラーを叩きます。
タスクスケジューラーは、暗号化に使用したアカウントの権限でスクリプトを実行します。
ユーザーアカウントはタスクスケジューラーのタスクを実行する権限が必要ですが、設定が容易です。
コラムの2は、エンドユーザーがイベントログをスクリプト経由で発行します。
タスクスケジューラーは発行されたイベントをトリガーとして、暗号化に使用したアカウントを用いて目的のスクリプトを実行します。
設定がやや煩雑になりますが、ユーザーはイベントログの発行する権限があれば実行できます。
終わりに
Powershell で簡単にパスワード等を暗号化する方法を紹介しました。
ちなみに今回はキーを使用しない方法を選びましたが、 ConvertFrom-SecureString は任意のキー(バイト配列)を使用することもできます。
こちらの方式であれば複数のユーザーや端末間でも共有が可能です。パスワードを暗号化するためのキーを平文で手元に残しておく必要があるので採用しませんでしたが、単に難読化したい場合はこちらもご検討ください。
スクリプト内での認証情報の保護やパスワードの暗号化の参考になれば幸いです。