1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

コマンドプロンプトでパスワード入力文字を見えなくする方法

Last updated at Posted at 2025-03-09

はじめに

仕事をしているとパスワードを入力する場面が何度もあります。共用サーバーの接続スクリプトなど自組織内で作成したスクリプトやバッチファイルを使う人も多いかと思いますが,入力したパスワードが平文のまま表示されてしまうバッチファイルに遭遇すると

こ の バ ッ チ を 作 っ た の は 誰 だ ! ?

と作者を呼び出したくなります。とはいえ,Windows のバッチファイルで入力パスワードの隠匿化を行うのはとても難しいようです。

ということで自作することにしました。良いアイデアが思い浮かんだので。

最初に結論を書く

それはエスケープシーケンスを使うというものです。Windows10 の途中で可能になったテクニックです。要は文字の色を背景色と同じにしてしまえば入力した文字は見えなくなります。サンプルコードを以下に示します。注意事項としてはパスワード入力後に文字の色と背景色を元に戻す必要があります。この際に改行なしでエスケープシーケンスを出力する必要があるので,ちょっとしたテクニック1を使っています。

エスケープシーケンス概説

エスケープシーケンスについての詳しい情報は Microsoft 公式サイト2 を参照下さい。以下は上記のバッチファイルで使った機能に関する部分のみを抜粋したものです。

表1 テキストの書式設定を行うエスケープシーケンス
シーケンス コード 説明 動作
ESC [ 0 m SGR 既定値 すべての属性を変更前の既定の状態に戻します
ESC [ 30 m SGR 前景白 非ボールドの明るい黒を前景に適用します
ESC [ 40 m SGR 背景白 非ボールドの明るい黒を背景に適用します

実行例

実行例を以下に示します。入力した文字は見えません。カーソルだけ見えます。

人によってはコマンドプロンプトの背景色を変えている人がいるかもしれません。その場合は何をやっているのかバレバレです。

注意事項

注意事項としては,文字の色を背景色と同じにして見えなくしているだけですから,パスワードを入力した付近を選択してコピー&ペーストすれば入力した文字を復元できます。なので早めに CLS コマンドを呼び出して画面クリアをしたほうが良いでしょう。

ちなみにパスワード入力中に Ctrl-C などで中断すると,それ以降文字が見えなくなってしまうのではないかと危惧したのですが,実際試してみると何故か Ctrl-C を二回連打しないと終了できなかったりと動作自体に謎は残るものの,既定の状態に戻すエスケープシーケンスが実行されて無事復帰できました。

補足)正統派な手段

おそらく一番正統派な解決手段3PowerShell を使うというものです。PowerShell だと下記のように DOTNET の機能を使えるので,奇をてらったテクニックを使うこともなく普通に書けます。SecureString オブジェクトになってしまうのは過剰包装的な感じもしますが。

test.ps1(PowerShell スクリプトの例)
$obj = Read-Host "Password" -AsSecureString
$str = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(sobj)
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($str)
Write-Host "Your entered password is $password"

実行画面もこれぞあるべき姿という感じです。

test.ps1 の実行画面
c:\Qiita>.\test.ps1
Password: ********
Your entered password is password

PowerShell 7.1 以降だともっとスッキリ書けます。

test2.ps1(PowerShell 7.1 以降で有効な方法)
$password = Read-Host "Password" -MaskInput
Write-Host "Your entered password is $password"

補足その2)超絶技巧

バッチファイルでも技巧を凝らせばできるという参考文献4のテクニックについても紹介しておきましょう。下記はオリジナルのエッセンスを自分なりに咀嚼して作り直したものです。特殊なテクニックを利用してパスワード文字列を一文字ずつ入力するほか,バックスペースによる修正にも対応しています。なおオリジナルは何も表示しませんが,アスタリスク * を表示するよう筆者が手を加えています。なお,パスワードの文字数も貴重な情報ですから,アスタリスクを表示してしまうのは改悪かもしれません。

実行例を以下に示しますが,とてもいい感じです。

上記のプログラムの基本原理(文字入力方法)についても説明しておきましょう。これは xcopy コマンドの /W オプション,すなわち「コピーを開始する前に任意のキーを押すことを求めるメッセージを表示する」機能を用いたものです。このオプションを用いると Enter キーなしの1文字入力が可能で,入力した文字を取得することができます。ちなみに pause コマンドも Enter キーなしの1文字入力待ちが可能ですが,入力した文字をエコーバックしないので,このような用途に用いることができません。

こうして出力された4行のうちの先頭行の末尾文字(下記の例では y)が入力された文字となります。また3行目だけは標準エラー出力に出力されるので NUL デバイスにリダイレクトして捨てる必要があります。

なお,xcopy コマンドで指定するコピー元ファイルは確実に存在しなくてはなりません。存在しなければメッセージが表示される前にエラー終了となるからです。このためコピー元とコピー先のファイルに自分自身 %0 を指定しています。

他には replace コマンドを使う方法もあります。replace コマンドは「指定されたドライブやディレクトリから同じファイルを探して置き換える」というコマンドです5/U オプションは送り側ファイルよりも古いファイルのみを置き換えるというもの,/W オプションはファイルの検索開始前に待機する(ユーザーのキー入力を待つ)というものです。カレントディレクトリに存在する名前が一文字のファイル(ワイルドカード ? にマッチングするファイル名)をカレントディレクトリ . にコピーしようとしているので仮にファイルが存在していてもタイムスタンプは必ず一致し,ファイルの置き換えは行われません。また一文字のファイルが存在しなくてもエラーにはなりません。

上記以外に驚いた点を以下述べます。

  • これまで for コマンドのループ変数は英字一文字(大文字・小文字は区別するので全52種)だと思っていたのですが,# とか英字以外の文字も使えるんですね。筆者が確認したところ,これ以外に @$_ などが変数名に使えるようです。

  • オリジナルプログラムではバックスペース記号を取得するために prompt コマンドを用いています。prompt コマンドではバックスペースを $H という印字可能な文字列で指定できるからです。こうして一時的にプロンプトをバックスペース記号に置き換え,これを読み出すことでバックスペース記号を取得しています。本記事ではバッチファイル内に直接バックスペース記号を埋め込んでいるので,このテクニックを使っていません。

ちなみに通常コマンドプロンプト上ではエスケープキーを押すと,その行の入力がキャンセルされますが,残念ながら上記の TEST2.CMD ではエスケープキーによる入力キャンセルに対応していません。これは xcopy コマンドを用いた文字入力方法ではエスケープキーの入力を検知できないからです。

おまけ

今回の記事で作成したバッチファイルです。

20250310_Password.zip (google-drive)

  1. 【バッチファイル】文字列を改行なしで表示【備忘録】- Qiita

  2. コンソールの仮想ターミナルシーケンス - learn.microsoft.com

  3. 【Bat+PowerShell】バッチファイルでパスワードなどの入力をマスクする(隠す)方法!- Correct-Log

  4. コマンドライン上で文字の見えないパスワード入力を実現する - Qiita

  5. Windowsコマンド集:(replace) - 日経クロステック

1
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?