1.Java暗号化拡張機能による暗号
Javaの開発環境はJDK1.5以上を対象にしていますが、最新版を利用することを推奨します。
1.1 概要
Java言語による暗号化をサンプルと共に説明しています。
JDK1.5以上には、JCE(Java 暗号化拡張機能)が含まれており、この機能を利用すると、共通鍵方式による暗号化や公開鍵方式による暗号化機能を実装できます。
JDK1.5以上には、JCE(Java 暗号化拡張機能)が含まれており、この機能を利用すると、共通鍵方式による暗号化や公開鍵方式による暗号化機能を実装できます。
このページでは、以下の手法を説明しています。
・ 共通鍵を自動生成して暗号化する
・ 共通鍵を作成して暗号化する(その1)[htt://www.trustss.co.jp/Java/JEncrypt122.html]
・ 共通鍵を作成して暗号化する(その2)[htt://www.trustss.co.jp/Java/JEncrypt123.html]
・ パスワードベース暗号化[htt://www.trustss.co.jp/Java/JEncrypt124.html]
また、Windowd APIとの連携として以下の説明もあります。
・ Javaで暗号化したデータをWindows APIで復号する[htt://www.trustss.co.jp/Java/JEncrypt130.html]
・ Windowsで暗号化したデータをJavaで復号する
ご参照ください。
・ 共通鍵を自動生成して暗号化する
・ 共通鍵を作成して暗号化する(その1)[htt://www.trustss.co.jp/Java/JEncrypt122.html]
・ 共通鍵を作成して暗号化する(その2)[htt://www.trustss.co.jp/Java/JEncrypt123.html]
・ パスワードベース暗号化[htt://www.trustss.co.jp/Java/JEncrypt124.html]
また、Windowd APIとの連携として以下の説明もあります。
・ Javaで暗号化したデータをWindows APIで復号する[htt://www.trustss.co.jp/Java/JEncrypt130.html]
・ Windowsで暗号化したデータをJavaで復号する
ご参照ください。
以下のページもご参照ください。
・Windows CryptoAPIによる暗号化の解説[http://www.trustss.co.jp/smnEncrypt010.html]
・Windowsの新しい暗号化(Cryptography Next Generation; CNG)APIによる暗号化の解説[http://www.trustss.co.jp/smnEncrypt010.html]
・XML文書の暗号化(共通鍵、公開鍵)[http://www.trustss.co.jp/dsig/index.html]
・XML文書への電子署名(Java編)[http://www.trustss.co.jp/dsig/Java/24100.html]
・XML文書への電子署名(C# .NetFramework編)[http://www.trustss.co.jp/dsig/CSharp/1100.html]
・Windows CryptoAPIによる暗号化の解説[http://www.trustss.co.jp/smnEncrypt010.html]
・Windowsの新しい暗号化(Cryptography Next Generation; CNG)APIによる暗号化の解説[http://www.trustss.co.jp/smnEncrypt010.html]
・XML文書の暗号化(共通鍵、公開鍵)[http://www.trustss.co.jp/dsig/index.html]
・XML文書への電子署名(Java編)[http://www.trustss.co.jp/dsig/Java/24100.html]
・XML文書への電子署名(C# .NetFramework編)[http://www.trustss.co.jp/dsig/CSharp/1100.html]
1.2 共通鍵方式(秘密鍵)での暗号化
Javaでは、共通鍵という言い方をせず、「秘密鍵」(Secret Key)といいます。本解説では、この表現にしたがって説明します。
また、この表現に従いますと、公開鍵方式の私有鍵に相当する秘密鍵の表現と混同しますので、「公開鍵」と「私有鍵」という表現に統一し、曖昧にならないようにしています。
秘密鍵による暗号化では、パスワードベース暗号化もサポートされていますのでその方法を含めて解説します。
また、この表現に従いますと、公開鍵方式の私有鍵に相当する秘密鍵の表現と混同しますので、「公開鍵」と「私有鍵」という表現に統一し、曖昧にならないようにしています。
秘密鍵による暗号化では、パスワードベース暗号化もサポートされていますのでその方法を含めて解説します。
1.2.1 暗号化と復号 (自動生成鍵による)
暗号化する秘密鍵を自動で生成して暗号化するコードを以下に示します。使用する暗号化アルゴリズムは「DES暗号」です。AES暗号化のサンプルは、「1.3.2 Javaによる暗号化(AES暗号)[http://www.trustss.co.jp/Java/JEncrypt130.html]」を参照してください。
暗号化と復号では、KeyGeneratorクラスを使って秘密鍵を生成し、Cipherクラスを使って暗号化と復号を行います。
ここで説明する方法で利用できる既定の暗号化のアルゴリズムは、暗号化アルゴリズムを参照してください。暗号化アルゴリズムは、鍵生成およびCipherの生成の際に指定します。
以下に暗号化と復号のコードを記します。
暗号化と復号では、KeyGeneratorクラスを使って秘密鍵を生成し、Cipherクラスを使って暗号化と復号を行います。
ここで説明する方法で利用できる既定の暗号化のアルゴリズムは、暗号化アルゴリズムを参照してください。暗号化アルゴリズムは、鍵生成およびCipherの生成の際に指定します。
以下に暗号化と復号のコードを記します。
/* * 暗号化と復号 */ import java.security.*; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; public class Encrypt01 { public static void main(String[] args) { try { /* * 暗号化 */ // (1)鍵の生成 KeyGenerator kg = KeyGenerator.getInstance("DES"); Key key = kg.generateKey(); // (2)暗号化準備 Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, key); byte input[] = "To be encrypted data.".getBytes(); // (3)暗号化の実施 byte encrypted[] = c.doFinal(input); // 暗号データ表示 PrintBin(encrypted); /* * (4)復号処理 */ // (5)復号準備 byte iv[] = c.getIV(); IvParameterSpec dps = new IvParameterSpec(iv); c.init(Cipher.DECRYPT_MODE, key, dps); // (6)復号の実施 byte output[] = c.doFinal(encrypted); // 復号結果表示 System.out.println("The string was \""); System.out.println(new String(output) + "\""); } catch (Exception e) { e.printStackTrace(); } } // 表示用メソッド public static void PrintBin(byte[] b){ for(int i=0; i<b.length; i++){ String h = Integer.toHexString(b[i]&0xFF); if((i+1)%8 == 0) { System.out.println(h+" "); }else{ System.out.print(h+" "); } } System.out.print("\n"); } }
暗号化では、鍵を生成し、その鍵を使ってデータ(クリアテキストといいます)を暗号化します。復号の際は、同じ鍵を使って暗号化されたデータを復号しています。
(1) 鍵の生成
KeyGeneratorクラスを使い鍵(Keyクラス)を生成します。KeyGenaratorクラスのインスタンスは、上記コードにあるgetInstance( )を利用します。この際に暗号化アルゴリズムを指定します。アルゴリズム名は大小文字を区別しません。
指定した暗号化アルゴリズムの秘密鍵は、generateKey( )で生成されます。このメソッドをコールするごとに新たな秘密鍵が(ランダムに)生成されます。
(2) 暗号化準備
暗号化では、Cipherクラスを使います。コードにあるようにgetInstance( )メソッドでインスタンスを要求します。このとき、引数には暗号化のアルゴリズム(algorithm)とともにモード(mode)とパディング(padding)方式を以下の形式で指定します。(モードとパディングについてをご参照ください。)
algorithm/mode/padding
モードおよびパディング方式は省略できますので
algorithm
と指定してもかまいません。省略された場合は、既定の値が適用されます。SunJCEの場合は、DES、DES-EDE、Blowfish暗号のデフォルトモードはECBで、パディング方式は PKCS5Paddingです。そのため、“DES/ECB/PKCS5Padding”と“DES”は同じです。
インスタンスを生成した後は、それを暗号化用に初期化します。init( )メソッドを使い、暗号化(ENCRYPT_MODE)の指定とともに生成した秘密鍵を与えます。
なお、復号の際にはDECRYPT_MODEの指定とともに生成した秘密鍵を与えます。
Cipherのインスタンスを要求する際に指定する暗号アルゴリズム/暗号化モード/パディング方式は以下のとおりです。(JDK1.6以上で指定できるものも含みます。)
暗号アルゴリズム - 暗号アルゴリズムとして(既定で)指定できるものは、以下のとおりですが、アルゴリズムによって具体的な実装方法が異なる場合がありますので注意してください。
(3) 暗号化の実施
暗号用に初期化された Cipherインスタンスを使って暗号化します。バイトデータを引数として Cipherインスタンスの doFinal( )をコールすると、暗号化されたデータを受け取れます。
(4) 復号処理
先ほどの暗号化で生成した秘密鍵および初期ベクトルを使って、暗号データを復号します。実際に復号するときは、これらのデータを復号する“人”のために取り出し、そして安全に渡さなければなりません。
(5)復号の準備
初期化ベクトルを暗号化の際に使用したCipherからgetIV( )メソッドで取り出します。これを使ってアルゴリズムパラメータのインスタンスを得ます。このアルゴリズムパラメータと秘密鍵を使って、暗号化で利用したと同じCipherインスタンスを生成しますが、上記のサンプルでは既に生成されたCipherインスタンスを利用します。
Cipherインスタンスは復号用に初期化します。
(6)復号の実施
復号用のCipherインスタンスで暗号化データを引数としてdoFinal( )をコールすると復号されたデータを取得できます。
次項では、暗号化の鍵を指定する方法を説明します。その後にパスワードなどから鍵を求めそれを使って暗号化する方法を説明します。
(1) 鍵の生成
KeyGeneratorクラスを使い鍵(Keyクラス)を生成します。KeyGenaratorクラスのインスタンスは、上記コードにあるgetInstance( )を利用します。この際に暗号化アルゴリズムを指定します。アルゴリズム名は大小文字を区別しません。
指定した暗号化アルゴリズムの秘密鍵は、generateKey( )で生成されます。このメソッドをコールするごとに新たな秘密鍵が(ランダムに)生成されます。
(2) 暗号化準備
暗号化では、Cipherクラスを使います。コードにあるようにgetInstance( )メソッドでインスタンスを要求します。このとき、引数には暗号化のアルゴリズム(algorithm)とともにモード(mode)とパディング(padding)方式を以下の形式で指定します。(モードとパディングについてをご参照ください。)
algorithm/mode/padding
モードおよびパディング方式は省略できますので
algorithm
と指定してもかまいません。省略された場合は、既定の値が適用されます。SunJCEの場合は、DES、DES-EDE、Blowfish暗号のデフォルトモードはECBで、パディング方式は PKCS5Paddingです。そのため、“DES/ECB/PKCS5Padding”と“DES”は同じです。
インスタンスを生成した後は、それを暗号化用に初期化します。init( )メソッドを使い、暗号化(ENCRYPT_MODE)の指定とともに生成した秘密鍵を与えます。
なお、復号の際にはDECRYPT_MODEの指定とともに生成した秘密鍵を与えます。
Cipherのインスタンスを要求する際に指定する暗号アルゴリズム/暗号化モード/パディング方式は以下のとおりです。(JDK1.6以上で指定できるものも含みます。)
暗号アルゴリズム - 暗号アルゴリズムとして(既定で)指定できるものは、以下のとおりですが、アルゴリズムによって具体的な実装方法が異なる場合がありますので注意してください。
- AES: Advanced Encryption Standard FIPS 197 標準
Rijindaelアルゴリズムとも呼ばれている。128bitのブロック暗号で、128/192/256bitの鍵長をサポートする。 - AESWrap:AES鍵ラッピングアルゴリズム
- ARCFOUR/RC4: Ron Rivest が開発したストリーム暗号。
- Blowfish: Bruce Schneier 氏の設計によるブロック暗号
- DES: Data Encryption Standard 共通鍵暗号 FIPS 46-3, FIPS 81 標準
- DESede: トリプル DES 暗号化 (DES-EDE)
- DESedeWrap: DESede鍵ラッピングアルゴリズム
- ECIES: Elliptic Curve Integrated Encryption Scheme
- PBEWith<digest>And<encryption> または PBEWith<prf>And<encryption>: パスワードベースの暗号アルゴリズム (PKCS #5) で、指定されたメッセージダイジェスト (<digest>) または擬似暗号関数(<prf>)、暗号アルゴリズム (<encryption>) を使用する。後ほど用例を示して説明します。
- RC2、RC4、および RC5: RSA Data Security, Inc の Ron Rivest により開発された可変キーサイズ暗号
- RSA: PKCS #1 で定義されている RSA 暗号
- NONE: モードなし
- CBC: FIPS PUB 81 で定義された Cipher Block Chaining Mode
- CFB、CFBx: FIPS PUB 81 で定義された Cipher Feedback Mode
CFBxモードを使うと、ブロック暗号は、暗号の実際のブロックサイズより小さい単位でデータを暗号化できる。 - CTR: OFBを単純化したもの。counterモードはカウンタとして入力ブロックを更新する。
- CTS: 『Applied Cryptography-Second Edition』に説明されている、Cipher Text Stealing。
- ECB: 米国商務省 National Institute of Standards and Technology (NIST) の Federal Information Processing Standard (FIPS) PUB 81「DES Modes of Operation」で定義された Electronic Codebook Mode (1980 年 12 月)
- OFB、OFBx: FIPS PUB 81 で定義された Output Feedback Mode
OFBxモードを使うと、ブロック暗号は、暗号の実際のブロックサイズより小さい単位でデータを暗号化できる。 - PCBC: Kerberos バージョン 4 で定義された Propagating Cipher Block Chaining
- ISO10126Padding: このブロック暗号用パディングは、W3C の「XML Encryption Syntax and Processing」ドキュメントに記載されている。
- NoPadding: パディングなし
- OAEPWith<digest>And<mgf>Padding: PKCS #1 に定義されている Optimal Asymmetric Encryption Padding スキーマ。
- PKCS1Padding: PKCS #1で説明されている。RSAアルゴリズムと共に利用される。
- PKCS5Padding: 「PKCS #5: Password-Based Encryption Standard」バージョン 1.5 (RSA Laboratories、1993 年 11 月) で規定されたパディング方式
- SSL3Padding: SSL Protocol バージョン 3.0 のセクション 5.2.3.2 (CBC ブロック暗号) で規定されたパディング方式
(3) 暗号化の実施
暗号用に初期化された Cipherインスタンスを使って暗号化します。バイトデータを引数として Cipherインスタンスの doFinal( )をコールすると、暗号化されたデータを受け取れます。
(4) 復号処理
先ほどの暗号化で生成した秘密鍵および初期ベクトルを使って、暗号データを復号します。実際に復号するときは、これらのデータを復号する“人”のために取り出し、そして安全に渡さなければなりません。
(5)復号の準備
初期化ベクトルを暗号化の際に使用したCipherからgetIV( )メソッドで取り出します。これを使ってアルゴリズムパラメータのインスタンスを得ます。このアルゴリズムパラメータと秘密鍵を使って、暗号化で利用したと同じCipherインスタンスを生成しますが、上記のサンプルでは既に生成されたCipherインスタンスを利用します。
Cipherインスタンスは復号用に初期化します。
(6)復号の実施
復号用のCipherインスタンスで暗号化データを引数としてdoFinal( )をコールすると復号されたデータを取得できます。
次項では、暗号化の鍵を指定する方法を説明します。その後にパスワードなどから鍵を求めそれを使って暗号化する方法を説明します。
暗号化モード、パディング方式について
このサンプルでは、暗号化モードをECB、パディング方式をPKCS5Paddingとしました。それぞれについて簡単に説明します。
- ECB
- PKCS5Padding
この暗号化モードは、暗号化をブロック毎に単純に繰り返すモードです。そのため、平文(暗号前の文書)にパターンの現れやすいテキストデータの暗号化には不向きとされ、バイナリーデータへの使用が推奨されています。
この暗号化モードの場合は、初期ベクタは不要です。
このパディング方式は、平文のバイト数がブロックサイズに満たなかった場合の不足分を追加する方式です。パディングされるバイト数は、1からブロックサイズまでです(0からではありません)。従いまして、平文のバイト数がちょうどブロックサイズの場合は、ブロックサイズと同じバイト数でパディングされます。
PKCS#5Paddingでは、「暗号化されたデータの最終バイトは追加されたパディングバイトでなければならない。」というルールがあります。パディングされたデータには、何バイト追加されたかという情報が含まれていますのでこのルールが必要になります。
PKCS#5Paddingでは、「暗号化されたデータの最終バイトは追加されたパディングバイトでなければならない。」というルールがあります。パディングされたデータには、何バイト追加されたかという情報が含まれていますのでこのルールが必要になります。
ご質問・ご要望
ご質問やご要望をお送りください。(匿名でも送信ください。ご質問やご要望内容は、公表しません。)
ご協力をお願いします、この記事は役に立ちましたか? | |
ご質問・ご要望 | |
メールアドレス | |
(記載の会社名および製品名は、各社の登録商標および商標です。)