これは、Googleを介して表示される最初のページであり、すべての実装のセキュリティの脆弱性に悩まされているため、元の投稿から7年経過しているため、他のユーザーの暗号化に関する情報を追加するためにこれを投稿しています。私はコンピューターエンジニアリングの修士号を取得し、暗号の勉強と学習に多くの時間を費やしたので、インターネットをより安全な場所にするために2セントを投入しています。
また、特定の状況では多くの実装が安全である可能性がありますが、なぜそれらを使用して誤って間違える可能性があることに注意してください。特別な理由がない限り、入手可能な最も強力なツールを使用してください。全体的に、ライブラリを使用し、できれば細かい詳細から離れることを強くお勧めします。
アップデート4/5/18:理解しやすくするためにいくつかの部分を書き直し、推奨ライブラリをJasyptからGoogleの新しいライブラリTinkに変更しました。既存の設定からJasyptを完全に削除することをお勧めします。
序文
安全な対称暗号化の基本を以下に概説し、人々が標準のJavaライブラリを使用して独自に暗号化を実装するときにオンラインで見られる一般的な間違いを指摘します。すべての詳細をスキップしたい場合は、Googleの新しいライブラリに移動します。Tinkをプロジェクトにインポートし、すべての暗号化にAES-GCMモードを使用すれば、安全です。
今あなたがJavaで暗号化する方法の要点を学びたいなら:)
ブロック暗号
まず最初に、対称鍵のブロック暗号を選択する必要があります。ブロック暗号は、疑似ランダムネスを作成するために使用されるコンピュータ機能/プログラムです。擬似ランダム性は、量子コンピュータ以外のコンピュータがそれと実際のランダム性の違いを識別できない偽のランダム性です。ブロック暗号は暗号化の基本要素のようなものであり、さまざまなモードやスキームで使用すると暗号化を作成できます。
さて、今日ブロック暗号アルゴリズムが利用可能については、確認してくださいNEVER、私は繰り返す決して使用しないDESを、私も絶対に使用しないでくださいと言うでしょう3DESを。SnowdenのNSAリリースでさえ、可能な限り疑似ランダムに近いことを確認できた唯一のブロック暗号はAES 256です。AES 128も存在します。違いは、AES 256が256ビットブロックで機能するのに対し、AES 128は128ブロックで機能することです。全体として、AES 128は安全であると見なされていますが、いくつかの弱点が発見されていますが、256はそれと同じくらい堅固です。
おもしろい事実DESは、NSAが最初に設立されたときにNSAによって破壊され、実際には数年間秘密にされていました。3DESは安全であるとまだ主張している人もいますが、3DESの弱点を見つけて分析した研究論文はかなりあります。
暗号化モード
暗号化は、ブロック暗号を取り、特定のスキームを使用するときに作成されます。これにより、ランダム性がキーと組み合わされ、キーを知っている限りリバーシブルなものが作成されます。これは暗号化モードと呼ばれます。
暗号化モードの例と、何が起こっているのかを視覚的に理解できるようにECBとして知られる最も単純なモードを次に示します。
最も一般的にオンラインで表示される暗号化モードは次のとおりです。
ECB CTR、CBC、GCM
リストされたモード以外にも他のモードが存在し、研究者は既存の問題を改善するために常に新しいモードに向けて取り組んでいます。
次に、実装と安全なものに移りましょう。ECBは絶対に使用しないでください。これは、有名なLinuxペンギンに示されているように、繰り返しデータを非表示にするのに適していません。
Javaで実装する場合、次のコードを使用すると、デフォルトでECBモードが設定されることに注意してください。
Cipher cipher = Cipher.getInstance("AES");
...危険これは脆弱性です!残念ながら、これはStackOverflow全体とオンラインでチュートリアルと例で見られます。
ナンスとIV
ECBモードで見つかった問題に対応して、IVとも呼ばれるアナウンスが作成されました。新しいランダム変数を生成し、それをすべての暗号化に添付することで、同じ2つのメッセージを暗号化すると、異なるメッセージが生成されるという考え方です。この背後にある美しさは、IVまたはnonceが公の知識であることです。これは、攻撃者がこれにアクセスできることを意味しますが、あなたの鍵がない限り、攻撃者はその知識で何もできません。
私が目にする一般的な問題は、人々がコード内の同じ固定値と同じようにIVを静的な値として設定することです。そして、IVを繰り返すときに、実際に暗号化のセキュリティ全体を危険にさらすときのIVの落とし穴があります。
ランダムIVの生成
SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
注: SHA1は壊れていますが、SHA256をこのユースケースに適切に実装する方法を見つけることができなかったため、誰かがこれをクラックして更新したい場合は、すばらしいでしょう!また、SHA1攻撃は従来とは異なり、巨大なクラスターでクラックが発生するまで数年かかる場合があります。詳細はこちら。
CTRの実装
CTRモードではパディングは必要ありません。
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
CBCの実装
CBCモードを実装する場合は、次のようにPKCS7Paddingを使用して実装します。
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
CBCおよびCTRの脆弱性とGCMを使用する理由
CBCやCTRなどの他のいくつかのモードは安全ですが、攻撃者が暗号化されたデータを反転させ、解読時にその値を変更するという問題に遭遇します。たとえば、架空の銀行のメッセージ「Sell 100」を暗号化するとします。暗号化されたメッセージは次のようになります。
これを回避するために、インターネットの大部分はGCMを使用しており、HTTPSが表示されるたびに、おそらくGCMを使用しています。GCMは暗号化されたメッセージにハッシュで署名し、この署名を使用してメッセージが変更されていないことを確認します。
GCMは複雑であるため、実装は避けます。Googleの新しいライブラリTinkを使用する方がよいでしょう。ここでも、誤ってIVを繰り返してしまうと、GCMの場合のキーが危険にさらされるため、これが究極のセキュリティ欠陥です。新しい研究者は、IVを繰り返しても暗号化モードに向けて取り組んでいます。IVを繰り返しても、キーは危険ではありませんが、これはまだ主流ではありません。
GCMを実装する場合は、ここにGCM実装へのリンクがあります。ただし、セキュリティを確保することはできず、適切に実装されているかどうかはわかりませんが、根拠が下がっています。また、GCMではパディングがないことに注意してください。
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
キーとパスワード
もう1つの非常に重要なメモは、暗号化に関して、キーとパスワードは同じものではないということです。暗号化のキーは、安全であると見なされるために、ある程度のエントロピーとランダム性を持っている必要があります。このため、適切な暗号化ライブラリを使用してキーを生成する必要があります。
したがって、ここで実行できる実装は2つあります。最初の実装は、このStackOverflowスレッドにあるコードを使用してランダムキーを生成することです。このソリューションでは、安全な乱数ジェネレータを使用して、使用できる鍵を最初から作成します。
安全性の低いもう1つのオプションは、パスワードなどのユーザー入力を使用することです。前述の問題は、パスワードに十分なエントロピーがないため、パスワードを取得して強化するアルゴリズムであるPBKDF2を使用する必要があることです。これが私が気に入ったStackOverflowの実装です。ただし、Google Tinkライブラリにはこれらすべてが組み込まれており、利用する必要があります。
Androidデベロッパー
ここで指摘すべき重要な点の1つは、Androidコードはリバースエンジニアリングが可能であり、ほとんどの場合、ほとんどのJavaコードもそうであるということです。つまり、コードにパスワードをプレーンテキストで格納する場合です。ハッカーは簡単にそれを取得できます。通常、これらのタイプの暗号化では、非対称暗号化などを使用します。これはこの投稿の範囲外であるため、ここでは詳しく説明しません。
2013年の興味深い記事:Androidでの暗号化の実装の88%が不適切に行われたことを指摘しています。
最終的な考え
ここでも、cryptoのJavaライブラリを直接実装せずにGoogle Tinkを使用することをお勧めします。これにより、すべてのアルゴリズムを適切に実装するという優れた仕事をしているので、頭痛の種を省くことができます。そして、それでも、Tink githubで出された問題、あちこちに存在する脆弱性のポップアップを確認するようにしてください。
質問やフィードバックがあれば、遠慮なくコメントしてください!セキュリティは常に変化しており、それに追いつくために最善を尽くす必要があります:)