web-dev-qa-db-ja.com

Java SecureStringと同等

.NETの SecureString.aspx に相当するJavaを探しています。 2018年に利用可能なそのような実装はありますか?

OWASP実装 は単純なchar配列なので、まったく同じではありません。 .NETの同等の機能は、アンマネージメモリとの間でインスタンスを取得したり、暗号化したりする機能など、 追加機能 を提供します。

私は一般的なJavaパスワードを_char[]_として渡すパターンを知っており、使用後にそれらをゼロでArrays.fill()を実行します。しかし、それは簡単なユーティリティクラスを構築する必要があります常に_char[]_あたり。

15

Oracleには GuardedString 実装があります。 .NETの SecureString ソリューションに最も近いものです。

パスワードをJava.lang.Stringとして保持することに関連する問題を解決する安全な文字列実装。つまり、文字列として表されるものはすべてクリアテキストのパスワードとしてメモリに保持され、少なくともガベージコレクションが行われるまでメモリに保持されます。

GuardedStringクラスは、文字を暗号化された形式でメモリに格納することにより、この問題を軽減します。暗号化キーはランダムに生成されたキーになります。

シリアル化された形式では、GuardedStringsは既知のデフォルトキーを使用して暗号化されます。これは、トランスポートに関係なく、最低レベルの保護を提供するためです。リモートコネクタフレームワークとの通信では、展開でSSLを有効にして真の暗号化を行うことをお勧めします。

アプリケーションはGuardedStringを永続化したい場合もあります。 Identity Managerの場合、GuardedStringsをEncryptedDataに変換して、Identity Managerの暗号化の管理機能を使用して保存および管理できるようにする必要があります。他のアプリケーションは、全体としてAPIConfigurationをシリアル化したい場合があります。これらのアプリケーションは、追加のセキュリティ層のためにAPIConfiguration blobを暗号化します(GuardedStringによって提供される基本的なデフォルトのキー暗号化を超えて)。

9
sanketshah

OWASPバージョンを変更して、メモリ内のchar配列をランダムにパディングして、静止しているchar配列に実際の文字が格納されないようにしました。

import Java.security.SecureRandom;
import Java.util.Arrays;


/**
* This is not a string but a CharSequence that can be cleared of its memory.
* Important for handling passwords. Represents text that should be kept
* confidential, such as by deleting it from computer memory when no longer
* needed or garbaged collected.
*/
public class SecureString implements CharSequence {

   private final int[] chars;
   private final int[] pad;

   public SecureString(final CharSequence original) {
      this(0, original.length(), original);
   }

   public SecureString(final int start, final int end, final CharSequence original) {
      final int length = end - start;
      pad = new int[length];
      chars = new int[length];
      scramble(start, length, original);
   }

   @Override
   public char charAt(final int i) {
      return (char) (pad[i] ^ chars[i]);
   }

   @Override
   public int length() {
      return chars.length;
   }

   @Override
   public CharSequence subSequence(final int start, final int end) {
      return new SecureString(start, end, this);
   }

   /**
    * Convert array back to String but not using toString(). See toString() docs
    * below.
    */
   public String asString() {
      final char[] value = new char[chars.length];
      for (int i = 0; i < value.length; i++) {
         value[i] = charAt(i);
      }
      return new String(value);
   }

   /**
    * Manually clear the underlying array holding the characters
    */
   public void clear() {
      Arrays.fill(chars, '0');
      Arrays.fill(pad, 0);
   }

   /**
    * Protect against using this class in log statements.
    * <p>
    * {@inheritDoc}
    */
   @Override
   public String toString() {
      return "Secure:XXXXX";
   }

   /**
    * Called by garbage collector.
    * <p>
    * {@inheritDoc}
    */
   @Override
   public void finalize() throws Throwable {
      clear();
      super.finalize();
   }

   /**
    * Randomly pad the characters to not store the real character in memory.
    *
    * @param start start of the {@code CharSequence}
    * @param length length of the {@code CharSequence}
    * @param characters the {@code CharSequence} to scramble
    */
   private void scramble(final int start, final int length, final CharSequence characters) {
      final SecureRandom random = new SecureRandom();
      for (int i = start; i < length; i++) {
         final char charAt = characters.charAt(i);
         pad[i] = random.nextInt();
         chars[i] = pad[i] ^ charAt;
      }
   }

}

2
Melloware