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(); } } }復号されたデータが表示されます。
ご質問・ご要望
ご質問やご要望をお送りください。(匿名でも送信ください。ご質問やご要望内容は、公表しません。)
ご協力をお願いします、この記事は役に立ちましたか? | |
ご質問・ご要望 | |
メールアドレス | |
(記載の会社名および製品名は、各社の登録商標および商標です。)