NIST Special Publication 800-38A のテストベクトルを確認した
NIST Special Publication 800-38A の付録 F に記載されているテストベクトルを入力した.testNISTAESCBC256() に記述している.
main.cpp
// AES-CBC テストベクトル確認 // http://www.ipa.go.jp/security/rfc/RFC3602JA.html#4 #include <iostream> #include <vector> #include <string> #include "../bytePrinter/bytePrinter.h" #include "../hexstring2bin/hexstring2bin.h" #include <aes.h> #include <cmath> using std::cout; using std::endl; void printInputData( const std::string &keyString, const std::string &ivString, const std::string &planetextString, const std::string &ciphertextString) { std::cout << "key : " << keyString << std::endl; std::cout << "iv : " << ivString << std::endl; std::cout << "planetext : " << planetextString << std::endl; std::cout << "ciphertext: " << ciphertextString << std::endl; } // 差の絶対値和を返す.負の数のときは何かおかしい int diff(const std::vector<unsigned char>&a, const unsigned char* b, size_t bLength ) { if ( a.size() != bLength ) return -1; int diff = 0; for ( size_t i = 0; i < bLength; i++ ) { diff += ::abs( a[i] - b[i] ); } return diff; } void testcase2() { cout << "AES-CBC-128 のテスト.RFC3602のテストベクトル" << endl; cout << "http://www.ipa.go.jp/security/rfc/RFC3602JA.html#4" << endl; const int TextLength = 32; std::string keyString("0xc286696d887c9aa0611bbb3e2025a45a"); std::string ivString("0x562e17996d093d28ddb3ba695a2e6f58"); std::string aString("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); std::string bString("0xd296cd94c2cccf8a3a863028b5e1dc0a7586602d253cfff91b8266bea6d61ab1"); printInputData(keyString,ivString,aString,bString); std::vector<unsigned char> key; std::vector<unsigned char> iv; std::vector<unsigned char> a; hexstring2bin::convert( keyString, key ); hexstring2bin::convert( ivString, iv ); hexstring2bin::convert( aString, a ); unsigned char b[TextLength]; unsigned char c[TextLength]; unsigned char workIv[TextLength]; ::memcpy_s (workIv, TextLength, iv.data(), iv.size() ); int result; aes_encrypt_ctx cxEnc; result = aes_encrypt_key128 ( key.data(), &cxEnc ); ::memcpy_s (workIv, TextLength, iv.data(), iv.size() ); result = aes_cbc_encrypt( a.data(), b, TextLength, workIv, &cxEnc); cout << "encrypted : "; bytePrinter::print( b, TextLength); aes_decrypt_ctx cxDec; result = aes_decrypt_key128 ( key.data(), &cxDec ); ::memcpy_s (workIv, TextLength, iv.data(), iv.size() ); result = aes_cbc_decrypt( b, c, TextLength, workIv, &cxDec); cout << "decrypted : "; bytePrinter::print( c, TextLength); cout << "平文一致 : " << diff ( a, c, TextLength ) << "(0 なら一致)" << endl; cout << "暗号文一致: " << diff ( a, c, TextLength ) << "(0 なら一致)" << endl; cout << endl; } void testaescbc256() { cout << "AES-CBC-256 のテスト.テストベクトル非準拠" << endl; const int TextLength = 32; std::string keyString("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); std::string ivString ("0x562e17996d093d28ddb3ba695a2e6f58"); std::string aString ("0x4596e435252346526ea0343434845758d47589375983a45983c5d83759374552"); std::string bString ("テストベクトルではないため未知"); // 49e4b393026fb9ea90b5fcfcdc413dd6bac5083becc7b5e693c0ea8156eef1c4 printInputData(keyString,ivString,aString,bString); std::vector<unsigned char> key; std::vector<unsigned char> iv; std::vector<unsigned char> a; hexstring2bin::convert( keyString, key ); hexstring2bin::convert( ivString, iv ); hexstring2bin::convert( aString, a ); unsigned char b[TextLength]; unsigned char c[TextLength]; unsigned char workIv[TextLength]; ::memcpy_s (workIv, TextLength, iv.data(), iv.size() ); int result; aes_encrypt_ctx cxEnc; result = aes_encrypt_key256 ( key.data(), &cxEnc ); ::memcpy_s (workIv, TextLength, iv.data(), iv.size() ); result = aes_cbc_encrypt( a.data(), b, TextLength, workIv, &cxEnc); cout << "encrypted : "; bytePrinter::print( b, TextLength); aes_decrypt_ctx cxDec; result = aes_decrypt_key256 ( key.data(), &cxDec ); ::memcpy_s (workIv, TextLength, iv.data(), iv.size() ); result = aes_cbc_decrypt( b, c, TextLength, workIv, &cxDec); cout << "decrypted : "; bytePrinter::print( c, TextLength); cout << "平文一致 : " << diff ( a, c, TextLength ) << "(0 なら一致)" << endl; cout << "暗号文一致: " << diff ( a, c, TextLength ) << "(0 なら一致)" << endl; cout << endl; } void testNISTAESCBC256() { // http://d.hatena.ne.jp/Guernsey/20091013/1255415857 // NIST Special Publication 800-38A の付録に記載されているテストベクトルを使用する // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf // 対象は 付録 F2.5 CBC-AES256.Encrypt および同 F2.6 CBC-AES256.Decrypt cout << "NIST Special Publication 800-38A 付録 F2.5 CBC-AES256.Encrypt および同 F2.6 CBC-AES256.Decrypt のテスト" << endl; cout << "http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf" << endl; const int TextLength = 64; std::string keyString("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"); std::string ivString ("000102030405060708090a0b0c0d0e0f"); std::string aString ("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"); std::string bString ("f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b"); printInputData(keyString,ivString,aString,bString); std::vector<unsigned char> key; std::vector<unsigned char> iv; std::vector<unsigned char> a; hexstring2bin::convert( keyString, key ); hexstring2bin::convert( ivString, iv ); hexstring2bin::convert( aString, a ); unsigned char b[TextLength]; unsigned char c[TextLength]; unsigned char workIv[TextLength]; ::memcpy_s (workIv, TextLength, iv.data(), iv.size() ); int result; aes_encrypt_ctx cxEnc; result = aes_encrypt_key256 ( key.data(), &cxEnc ); ::memcpy_s (workIv, TextLength, iv.data(), iv.size() ); result = aes_cbc_encrypt( a.data(), b, TextLength, workIv, &cxEnc); cout << "encrypted : "; bytePrinter::print( b, TextLength); aes_decrypt_ctx cxDec; result = aes_decrypt_key256 ( key.data(), &cxDec ); ::memcpy_s (workIv, TextLength, iv.data(), iv.size() ); result = aes_cbc_decrypt( b, c, TextLength, workIv, &cxDec); cout << "decrypted : "; bytePrinter::print( c, TextLength); cout << "平文一致 : " << diff ( a, c, TextLength ) << "(0 なら一致)" << endl; cout << "暗号文一致: " << diff ( a, c, TextLength ) << "(0 なら一致)" << endl; cout << endl; } int main () { aes_init(); testcase2(); testaescbc256(); testNISTAESCBC256(); return 0; }