コンソールでのパスワード入力


コンソールでパスワード入力するときに画面上に文字が表示されてしまってはセキュリティ上よろしくないので表示されないようにします。秘密にしたい文字列は SecureString を使えと書いてあります。ドキュメントを読んでも良くわからないので適当に書いてみました。

Console.Write("Input Password: ");
using (SecureString password = new SecureString())
{
	while (true)
	{
		ConsoleKeyInfo input = Console.ReadKey(true);
		if (input.Key == ConsoleKey.Enter)
		{
			Console.WriteLine();
			break;
		}
		else if (input.Key == ConsoleKey.Backspace)
		{
			if (password.Length > 0)
			{
				password.RemoveAt(password.Length - 1);
			}
		}
		else if (IsValidPasswordCharacter(input.KeyChar))  // 適当に実装
		{
			password.AppendChar(input.KeyChar);
		}
	}
	password.MakeReadOnly();

	IntPtr p = Marshal.SecureStringToBSTR(password);
	Console.WriteLine(Marshal.PtrToStringAuto(p));
	Marshal.ZeroFreeBSTR(p);
}

秘匿したパスワードを出力しているのはさておき,よくわからないのは PtrToStringAuto で string に結局コピーされるので本当にセキュアなのかどうなのかという点です。 string にコピーされると破棄されるタイミングはガベコレの気分次第になってしまい, GC.Collect() に頼るくらいしか思い当たらないです。