1.3 Java暗号とWindows暗号の連携

 Javaの開発環境は、JDK1.5以上を想定しています。
 別に、XML文書への暗号化や電子署名 を説明しています。

1.3.1 概要

 Javaで暗号化(AES共通鍵暗号化)したデータをWindows APIで復号する方法を解説します。
 Windows環境は、以下を対象とします。
   OS: Windows XP,2003,Vista
   開発環境: Visual Studio 2005 C++

Javaによる暗号化の詳細こちら[http://www.trustss.co.jp/Java/JEncrypt100.html]Windowsによる暗号化の詳細こちら[http://www.trustss.co.jp/cng/1000.html]を参照してください。

1.3.2 Javaで暗号化する (AES暗号)

 ここでは、AES暗号アルゴリズムを使って解説します。
 実際のアプリケーションで暗号化を実施する場合は、暗号化の鍵を直接指定せずあらかじめ与えられたパスワードやPINなどの情報から利用するアルゴリズムに適した長さの共通鍵を生成するのが容易です。ここでは、わかりやすくするために暗号化の鍵を直接指定して暗号化・復号を行う方法を説明します。
 暗号鍵を指定した暗号化パスワードなどから鍵を生成して暗号化する方法の解説は、それぞれのページを参照してください。

まず、Javaでテキストデータを暗号化します。以下のコードは、暗号鍵を指定した暗号化で説明したコードと同様ですが、暗号化のアルゴリズムは128ビットAESを選択しています。暗号化モードは、ECBとし初期化ベクターを不要にしています。
 なお日本国内であれば、AES鍵長を128ビットばかりではなく192ビットや512ビットで使うことができます。JCEの初期状態では利用できませんが、「1.4 JCEを無制限強度にする[http://www.trustss.co.jp/Java/JEncrypt140.html]
」の手順に従えば、利用できるようになります。
import java.io.*;
import javax.crypto.Cipher;
import javax.crypto.spec.*;

public class AesJavaEnc {

    public static void main(String[] args) {
        try {
            // 鍵
            byte[] kagi = { 0x00, 0x01, 0x02, 0x03,
                            0x04, 0x05, 0x06, 0x07,
                            0x08, 0x09, 0x0a, 0x0b,
                            0x0c, 0x0d, 0x0e, 0x0f };
            SecretKeySpec sks = new SecretKeySpec(kagi,0,16,"AES");

            // 暗号化
            Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
            c.init(Cipher.ENCRYPT_MODE, sks);
            byte input[] = "This ia an original message.".getBytes();
            byte encrypted[] = c.doFinal(input);

            // 暗号化したデータを保存
            FileOutputStream fe = new FileOutputStream("a.enc");
            fe.write(encrypted);
            fe.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
鍵は、共通鍵鍵ですので同じものを復号時に使います。また、暗号化したデータはa.encという名前で保存します。次は、このファイルからデータを読み出し、復号します。

1.3.3 Windows APIで復号する

 Windowsでは、CNG(Cryptography Next Genaration)APIを使って復号します。詳細は、CNG APIによる暗号化[http://www.trustss.co.jp/cng/1000.html]を参照してください。
#include <BCrypt.h>

#pragma comment(lib, "BCrypt.lib")

#define    NT_SUCCESS(Status)   (((NTSTATUS)(Status)) >= 0)
#define    STATUS_UNSUCCESSFUL   ((NTSTATUS)0xC0000001L)

// 共通鍵(暗号化で用いたものと全く同じ)
static const BYTE    rgbAES128Key[] = {
           0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
           0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };

void main(int argc, char **argv)
{
    BCRYPT_ALG_HANDLE       hAesAlg = NULL;
    BCRYPT_HANDLE           hAlg    = NULL;
    BCRYPT_KEY_HANDLE       hKey    = NULL;
    NTSTATUS                status  = STATUS_UNSUCCESSFUL;
    BYTE    pbCipherText[1000];
    BYTE    pbPlainText[1000];
    DWORD   cbCipherText = 1000,
            cbPlainText  = 1000,
            cbKeyObject  	= 0,
            cbData;
    PBYTE   pbPlainText  = NULL,
            pbKeyObject  	= NULL;

    // アルゴリズムハンドル
    status = BCryptOpenAlgorithmProvider(
                           &hAesAlg,
                           BCRYPT_AES_ALGORITHM,
                           NULL,
                           0);
    if(!NT_SUCCESS(status)) {
        printf("*** Error 0x%x returned by the function\n", status);
        goto Cleanup;
    }

    // 暗号化モード
    status = BCryptSetProperty(
                    hAesAlg,
                    BCRYPT_CHAINING_MODE,
                    (PBYTE)BCRYPT_CHAIN_MODE_ECB,
                    sizeof(BCRYPT_CHAIN_MODE_ECB),
                    0);
    if(!NT_SUCCESS(status)) {
        printf("*** Error 0x%x returned by the function\n", status);
        goto Cleanup;
    }

    // 鍵オブジェクトの大きさを計算
    status = BCryptGetProperty(
                    hAesAlg,
                    BCRYPT_OBJECT_LENGTH,
                    (PBYTE)&cbKeyObject,
                    sizeof(DWORD),
                    &cbData,
                    0);
    if(!NT_SUCCESS(status)) {
        printf("*** Error 0x%x returned by the function\n", status);
        goto Cleanup;
    }

    // 鍵オブジェクト用の領域を確保
    pbKeyObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbKeyObject);
    if(!pbKeyObject) {
        printf("*** memory allocation failed\n");
        goto Cleanup;
    }

    // 鍵オブジェクトを鍵データから生成
    status = BCryptGenerateSymmetricKey(
                        hAesAlg,
                        &hKey,
                        pbKeyObject,
                        cbKeyObject,
                        (PBYTE)rgbAES128Key,
                        sizeof(rgbAES128Key),
                        0);
    if(!NT_SUCCESS(status)) {
        printf("*** Error 0x%x returned by the function\n", status);
        goto Cleanup;
    }

    // 暗号化データをファイルから読み出す
    FILE    *fp;
    fopen_s(&fp, "a.enc", "rb");
    cbCipherText = (DWORD)fread(pbCipherText, 1, cbCipherText, fp);
    fclose(fp);

    // 復号
    status = BCryptDecrypt(
                    hKey,
                    pbCipherText,
                    cbCipherText,
                    NULL,
                    NULL,
                    0,
                    pbPlainText,
                    cbPlainText,
                    &cbPlainText,
                    BCRYPT_BLOCK_PADDING); // PKCS#5パディング
    if(!NT_SUCCESS(status)) {
        printf("*** Error 0x%x returned by the function\n", status);
        goto Cleanup;
    }

    Cleanup:
    if(hAesAlg) { BCryptCloseAlgorithmProvider(hAesAlg, 0); }
    if(hKey) { BCryptDestroyKey(hKey); }
    if(pbKeyObject) { HeapFree(GetProcessHeap(), 0, pbKeyObject); }
}
復号されたデータは、pbPlainTextに入り、その大きさはcbPlainTextバイトです。


次は、Windowsで暗号化したデータをJavaで復号します。
総合目次 <<< >>> 次のページ[http://www.trustss.co.jp/Java/JEncrypt134.html]

 ご質問・ご要望

 ご質問やご要望をお送りください。(匿名でも送信ください。ご質問やご要望内容は、公表しません。)
ご協力をお願いします、この記事は役に立ちましたか?
ご質問・ご要望
メールアドレス


(記載の会社名および製品名は、各社の登録商標および商標です。)

PDF-Tools
PDFおよびPDF/Aを作成・編集などができるJavaで使えるライブラリ
128ビットの暗号化や電子署名に対応
http:
//www.trustss.co.jp/pdf/
1. Java暗号化拡張機能による暗号
1.1 概要
1.2 共通鍵方式(秘密鍵)での暗号化
1.2.1 暗号化と復号 (自動生成鍵による)
1.2.2 暗号鍵を指定して暗号化する
1.2.3 パスワードなどから暗号鍵を生成する
1.2.4 パスワードベース暗号化(PBE)方式
 
1.3 Java暗号とWindows暗号の連携
1.3.1 概要
1.3.2 Javaで暗号化する
1.3.3 Windows APIで復号する
1.3.4 Windowsで暗号化する
1.3.5 Javaで復号する
 
1.4 JCE 暗号を無制限強度にする
3. Javaによる 電子署名の検証
3.1 概要
3.2 電子署名されたデータ
3.3 署名されたデータから電子証明書を取り出す
3.4 Windows証明書ストアから、ルート証明書を取り出す
3.5 DLLおよびサンプルコード
参考
Windows CryptoAPIによる暗号化
Windowsの新しい暗号化API
XML文書の暗号化
XML文書への電子署名(Java)
XML文書への電子署名(C#)
株)トラスト・ソフトウェア・システム
暗号化・電子署名・タイムスタンプ ライブラリ作成します。
お問い合わせください。
会員用ログイン
ID:
パスワード:
ログインすると、一般公開していないページを閲覧できます。