Java の Console クラスの readPassword メソッドを用いたパスワードの入力

コンソールとは?

あとで Java のコードを紹介しますが、そこでコンソールという言葉が出てきますので、先にコンソールという言葉の意味を説明しておきます。

本来の意味では、コンピュータに命令を入力する物理的な装置のことを「ターミナル」(端末) といいます。 そして、ターミナルのうち文字・テキストによって命令を入力するテキスト端末のことを「コンソール」といいます。

ターミナルとして動作するソフトウェアのことを「ターミナル・エミュレータ」といいますが、慣例的には単に「ターミナル」とも言ったりします。

Windows に含まれるターミナル (エミュレータ) は「コマンドプロンプト」という名前のプログラムです。macOS ではその名の通り「ターミナル」という名前が付いています。

コンソールも同様で、ソフトウェアでその機能を実現するものを「仮想コンソール」とかあるいは単に「コンソール」といいます。

以上から結局、パソコン上のプログラム開発をしている時に単に「コンソール」といったら「コマンドプロンプト」(Windows) や「ターミナル」(mac) などの、 テキストベースのコマンド実行環境のことを指します。

パスワードの危ない入力方法

それでは実際に、ユーザーからの入力を受け取るプログラムを書いてみましょう。

Java でコンソールからの入力を受けとる簡単な方法として、Scanner クラスを利用する方法があります。

次のコードでは Scanner クラスの nextLine() でユーザーからの入力を受け取っています。

import java.util.Scanner;

public class PasswordTest1A {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);

    System.out.print("Enter username: ");
    String name = in.nextLine();
    System.out.print("Enter password: ");
    String password = in.nextLine();

    showResult(name, password);
  }

  public static void showResult(String name, String password) {
    System.out.println("==========");
    System.out.println("Username: " + name);
    System.out.println("Password: " + password);
  }
}

入力を受け取ったら、その内容をそのまま表示しています。

このプログラムを実行すると、次のようになります。

これを見てわかるように、パスワードとして入力したい文字も、画面にタイプした内容がそのままエコーされて表示されてしまっています。 パスワードの入力形式としては大変危険です。

Console クラスの readPassword() メソッドでパスワードを安全に入力

そこで、次のようにパスワードの入力内容が画面に表示されないように修正しましょう。

これは macOS の Terminal での実行結果ですが、ここでは鍵アイコンが表示されて、入力内容が伏せられていることがわかります。

こうした動作はどのように実装すればよいでしょうか。

上では Scanner クラスの nextLine() メソッドを使って、 コンソールでの入寮内容を受け取りましたが、この方法を変更して、Console クラスを利用します。

Console クラスはパスワードを読み取ることを想定した readPassword() メソッドを持っています。これを使うと、 タイプした内容をローカルエコーしません。

import java.io.Console;

public class PasswordTest1B {
  public static void main(String[] args) {
    Console cons = System.console();

    if (cons == null) {
      System.out.println("con == null");
      return;
    }

    String name = cons.readLine("Enter username: ");
    char[] inChars = cons.readPassword("Enter password: ");
    String password = new String(inChars);

    showResult(name, password);
  }

  public static void showResult(String name, String password) {
    System.out.println("==========");
    System.out.println("Username: " + name);
    System.out.println("Password: " + password);
  }
}

Console クラスの readLine メソッドと readPassword メソッドを利用してコンソールへの入力を受け取っています。 どちらのメソッドも入力を促すプロンプトの文字列を受け取り、それを表示することができます。

現在のセッションでの Console オブジェクトは System.console() の戻り値として取得します。

Console が null の場合

このプログラムを Eclipse や IntelliJ などの統合開発環境で実行すると、System.console()Console オブジェクトが取得できない場合があります。これは現在のセッションがコンソールに関連付けされていないためです。

その場合は、例えば IntelliJ なら IDE 内部でも Terminal を開く機能がありますので、そこで実行します。

あるいはターミナルを開いて、IDE の外でプログラムを実行すれば Console オブジェクトが取得できるはずです。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Java 入門