2012-03-05 9 views
11

認証された暗号化では、メッセージの暗号化と認証にいくつかの標準を使用する必要があります。そこで我々は、メッセージを暗号化し、改ざんされていないことを確認するためにメッセージ上のMACを計算する。Javaで認証された暗号化を実行する適切な方法は何ですか?

This questionは、パスワードベースの鍵の強化と暗号化を実行する方法について概説:

/* Derive the key, given password and salt. */ 
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256); 
SecretKey tmp = factory.generateSecret(spec); 
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
/* Encrypt the message. */ 
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
cipher.init(Cipher.ENCRYPT_MODE, secret); 
AlgorithmParameters params = cipher.getParameters(); 
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); 
byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8")); 

をしかし、私の知る限り、これは暗号文に任意のMACを計算していないので、安全ではないだろう。 Javaで認証された暗号化を実行するために受け入れられる標準は何ですか?

+0

あなたが知っている完全なメッセージを暗号化/復号化する場合、それは改ざんされていません。 「プレーンテキスト」でメッセージ(またはデータ)を送信してからプレーンテキストを認証するためにHMACを送信する場合は、HMACは使用されていませんか? – TacticalCoder

+0

認証された暗号化を行うための標準はありません。(非対称な)シグネチャ、MAC(例:AESCMAC)、HMAC、または認証モードなどがあります。しかし、いくつかの安全でないものがあります(デフォルトのAES-MACはあまり安全ではありません)。あなたのユースケースに合った良い答えは下記をご覧ください。 –

+0

答えに何か問題がありますか? –

答えて

11

GCMモード暗号化の使用をおすすめします。これはデフォルトで最新のJDK(1.7)に含まれています。これは、カウンタモードの暗号化(ストリーム暗号、パディングなし)を使用し、認証タグを追加します。大きな利点の1つは、HMACが別のキーをミックスに追加するのに対し、単一のキーだけを必要とすることです。 Bouncy Castleには実装もあり、Oracleが提供するものと互換性があります。

GCMモードの暗号化は、TLS RFCの機能でもあり、XML暗号化1.1の機能(どちらも最終的ではありません)です。 GCMモードでは、データの機密性、完全性、信頼性の3つのセキュリティ機能がすべて提供されます。ストリングは、現在展開しているCBCの代わりに "AES/GCM/NoPadding"になります。 Oracleから最新のJDKを入手しているか、またはBouncy Castleプロバイダをインストールしていることを確認してください。

また、私の答えはhereです。これは主に文字列エンコーディングに関するものですが、私もGCMモードも試みました。コメントを参照してください。

+0

ストリーム暗号と同様に、NONCE/IV同じ価値を再付与することは、不安につながるであろう。 –

+0

そうです、これはすべてが考慮された最良の答えだと思います。私はJDK 1.6を使用するように制限されているので、パスワードベースのキー強化を実行して256ビットのキーを生成するソリューションを検討しました。私は鍵の最初の128ビットを取り出し、それをAES CBCを使用して暗号化し、最後に128ビットを使用して暗号文をMACにします。 –

+0

@EricConnerも初期化ベクトルをMACに忘れてはいけません! – MauganRa

3

セキュリティで保護されたftpを使用してあるサーバーから別のサーバーにファイルを転送するとき、私は「差出人」サーバーにある秘密キーと「to」サーバーにある公開キーとを使用します。

秘密鍵と公開鍵のペアを使用することは、ファイルを転送する際の安全な標準です。

私はそれがJavaアプリケーションの文脈では安全な手段であると信じています。

Javaのデジタル署名のプライベート/公開鍵ペアの設定の詳細については、Generating and Verifying SignaturesGenerate Public and Private Keys を参照してください。

+0

これはまったく新しいユースケースですが、私はちょっと厳しいものでした。シグネチャとPKI *は、整合性の制御と認証の有効な方法ですが、MACを計算するにはかなり重い方法です。 –

+1

@owlstead - 元のコメントを簡単に思い出しましたが、削除されたように見えます。いずれにせよ心配はありません。私はいくつかの人々が私の答えをdownvoteしてきたと私はいくつかのケースでなぜ理解する。私はdownvoteの上を浮遊するときに見られる理由のためにもっと多くの人々downvoteを望んでいます - "この答えは有用ではありません"。この場合、私は私の答えがOPを助けることができると信じており、それが私が投稿した理由です。神は私たちの誰かがポイントのために何かを投げ捨てることを禁じています。私たち全員が最終的にお互いを助けようと努力しなければなりません。 –

+0

それは、それがむしろ過酷であると思った理由です。私は自分自身が時にはネガティブすぎるのをやめなければなりません。私はFTPとRSAがEricが探していたものかどうか分かりませんが、間違っているわけではないので、答えは自分のために戦い続けなければなりません... –

関連する問題