1.3 Java暗号とWindows暗号の連携

 Windowsで暗号化したデータを、Javaで復号する方法を説明します。

1.3.4 Windowsで暗号化する (AES暗号)

 WindowsのAPIでテキストデータを暗号化します。以下のコードは、共通鍵による簡単な暗号化[http://www.trustss.co.jp/cng/1000.html]で説明したコードと同様ですが、暗号化のアルゴリズムは128ビットAESを選択しています。暗号化モードは、ECBとし初期化ベクターを不要にしています。
#include <Windows.h>
#include <Bcrypt.h>

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

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

// データ
static const BYTE rgbPlainText[] = { "This is an original Message" };

// 共通鍵
static const BYTE	rgbAES128Key[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };


int _tmain(int argc, _TCHAR* argv[])
{
    BCRYPT_ALG_HANDLE	hAesAlg = NULL;
    BCRYPT_KEY_HANDLE	hKey = NULL;
    BYTE pbCipherText[100];
    DWORD	cbKeyObject = 0,
           cbCipherText = 100,
           cbData;
    PBYTE pbKeyObject = NULL;
    NTSTATUS status = STATUS_UNSUCCESSFULL;

    // Open an algorithm handle.
    status = BCryptOpenAlgorithmProvider(
        &hAesAlg,
        BCRYPT_AES_ALGORITHM,
        NULL,
        0);
    if(!NT_SUCCESS(status)) {
        printf("*** Error 0x%x returned by the function\n", status);
        return 1;
    }

    // 暗号化モード
    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);
        return 1;
    }

    // 鍵オブジェクトの大きさを計算
    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);
        return 1;
    }

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

    // 鍵オブジェクトを鍵データから作成
    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);
        return 1;
    }

    // 暗号化
    status = BCryptEncrypt(
        hKey,
        (PBYTE)rgbPlainText,
        sizeof(rgbPlainText),
        NULL,
        NULL,
        0,
        pbCipherText,
        cbCipherText,
        &cbData,
        BCRYPT_BLOCK_PADDING);
    if(!NT_SUCCESS(status)) {
        printf("*** Error 0x%x returned by the function\n", status);
        return 1;
    }

    // 暗号化データをファイルに書き出す
    FILE *fp;
    fopen_s(&fp, "a.enc", "wb");
    fwrite(pbCipherText, 1, cbData, fp);
    fclose(fp);

    // 後始末
    status = BCryptDestroyKey(hKey);
    if(!NT_SUCCESS(status)) {
        printf("*** Error 0x%x returned by the function\n", status);
        return 1;
    }

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

1.3.5 Javaで復号する

import java.io.*;
import javax.crypto.Cipher;
import javax.crypto.spec.*;

public class AesJavaDec {
    public static void main(String[] args) {
    try {
            // 鍵
            byte[] kagi = { 0, 1, 2, 3, 4, 5, 6, 7,
                            8, 9, 10, 11, 12, 13, 14, 15 };
            SecretKeySpec sks = new SecretKeySpec(kagi, 0, 16, "AES");
			
            // 暗号化データ読み込み
            byte[] input = new byte[32];
            FileInputStream fe =new FileInputStream("a.enc");
            fe.read(input);
            fe.close();
			
            // 復号
            Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
            c.init(Cipher.DECRYPT_MODE, sks);
            byte output[] = c.doFinal(input);
			
            System.out.println(new String(output));
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}
復号されたデータが表示されます。


 ご質問・ご要望

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


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

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:
パスワード:
ログインすると、一般公開していないページを閲覧できます。