web-dev-qa-db-ja.com

Java-構成ファイルからユーザー名とパスワードを暗号化/復号化する

Javaクライアント用のWebサービスを開発しています。2つの選択肢があります:

  • 暗号化されたユーザー名/パスワードをWebサービスクライアントに保存します。構成から読み取ります。クライアント側のファイル、復号化して送信します。

  • 暗号化されたユーザー名/パスワードをWebサーバーに保存します。構成から読み取ります。 Webサーバー上のファイル、復号化してWebサービスで使用します。

ユーザー名/パスワードは、サードパーティのアプリケーションにアクセスするためにWebサービスによって使用されます。

クライアントにはすでにこの機能を提供するクラスがありますが、このアプローチには、(イントラネット内ではあるが)平文でユーザー名/パスワードを送信することが含まれます。彼らは情報を保存することを好みます。 Webサービス内ではありますが、すでに持っているものに対しては支払いたくありません。 (イントラネット内にのみ存在するため、セキュリティは大きな考慮事項ではありません)。

したがって、Javaですばやく簡単なものが必要です。

何かお勧めですか?

サーバーはTomkat 5.5です。 WebサービスはAxis2です。

  • どの暗号化/復号化パッケージを使用する必要がありますか?
  • キーストアはどうですか?
  • どの構成メカニズムを使用する必要がありますか?
  • これは簡単に導入できますか?
14
nzpcmad

イントラネット上にいることは、確かにセキュリティを却下することを正当化しません。情報への被害のほとんどは内部関係者によるものです。保護対象の価値を確認し、セキュリティを十分に考慮してください。

資格情報のセットが1つあるサードパーティアプリケーションと、サードパーティアプリケーションを使用するときにこのIDを効果的に共有するクライアントがあるようです。その場合は、次の方法をお勧めします。

サードパーティのパスワードをWebサーバー以外に配布しないでください。

これを行う最も安全な方法は、それをWebアプリケーションにインタラクティブに提供することです。これは、アプリケーションの起動時にパスワードを要求するServletContextListenerか、管理者がフォームから入力できるようにアプリケーション内のページである可能性があります。パスワードはServletContextに格納され、サードパーティサービスへのリクエストを認証するために使用されます。

安全性を下げるには、サーバーのファイルシステムにパスワードを保存して、サーバーを実行しているユーザーだけがパスワードを読み取れるようにします。これは、サーバーのファイルシステムのアクセス許可に依存して保護されます。

暗号化された形式のパスワードをクライアントまたはサーバーに保存しようとすることは、1つ後ろに進んでいるだけです。秘密を別の秘密で保護しようとすると、無限の退行に陥ります。

さらに、クライアントはサーバーに対して自身を認証する必要があります。クライアントが対話型の場合は、ユーザーにパスワードを入力してもらいます。サーバーは、そのユーザーがサードパーティのサービスへのアクセスを許可されているかどうかを判断できます。クライアントがインタラクティブでない場合、次善の策は、ファイルシステムのアクセス許可を使用してクライアントのパスワードを保護することです。

クライアントの資格情報を保護するには、クライアントとWebサーバー間のチャネルをSSLで保護する必要があります。ここでは、サーバーで自己署名証明書を使用できるため、イントラネットでの操作が有利です。

パスワードをファイルに保存する場合は、パスワードを自分でファイルに入れてください。アクセス許可を注意深く管理する必要性がより目立つようになり、多くのユーザーがそのファイルを編集してパスワードを見る必要が最小限になります。

18
erickson

とにかく私が理解しているように、サードパーティのWebサービスを呼び出すには、パスワードをプレーンテキストで渡し、セキュリティ証明書は必要ありません。

次に、最も簡単なアプローチは、暗号化/復号化キーがコードにハードコードされている場合に、暗号化された形式でパスワードを保存することです(Java暗号化メカニズム))。

複数のクライアントに配布して維持するのではなく、サーバー側(ファイルシステムまたはdb)に確実に保存します。

これが「DES」暗号化でどのように機能するかを示します。

// only the first 8 Bytes of the constructor argument are used 
// as material for generating the keySpec
DESKeySpec keySpec = new DESKeySpec("YourSecr".getBytes("UTF8")); 
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
Sun.misc.BASE64Encoder base64encoder = new BASE64Encoder();
Sun.misc.BASE64Decoder base64decoder = new BASE64Decoder();
.........

// ENCODE plainTextPassword String
byte[] cleartext = plainTextPassword.getBytes("UTF8");      

Cipher cipher = Cipher.getInstance("DES"); // cipher is not thread safe
cipher.init(Cipher.ENCRYPT_MODE, key);
String encrypedPwd = base64encoder.encode(cipher.doFinal(cleartext));
// now you can store it 
......

// DECODE encryptedPwd String
byte[] encrypedPwdBytes = base64decoder.decodeBuffer(encryptedPwd);

Cipher cipher = Cipher.getInstance("DES");// cipher is not thread safe
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainTextPwdBytes = (cipher.doFinal(encrypedPwdBytes));
26