#include <aes/esp_aes.h>
#include "base64.hpp"
// AES CBCで暗号化
void encodeAes(const uint8_t key[32], uint8_t iv_base[16], char* plaintext, char* encrypted) {
// IVは変更されるのでコピーを作成
uint8_t iv[16];
memcpy( iv, iv_base, sizeof( iv ) );
// 暗号化
esp_aes_context ctx;
esp_aes_init( &ctx );
esp_aes_setkey( &ctx, key, 256 );
int len = ( ( strlen(plaintext) + 15 ) / 16 ) * 16;
esp_aes_crypt_cbc( &ctx, ESP_AES_ENCRYPT, len, iv, (uint8_t*)plaintext, (uint8_t*)encrypted );
esp_aes_free( &ctx );
}
// AES CBCで復号化
// base64 => uint8_t
void decodeAes(const uint8_t key[32], uint8_t iv_base[16], char* plaintext, char* encrypted) {
// IVは変更されるのでコピーを作成
uint8_t iv[16];
memcpy( iv, iv_base, sizeof( iv ) );
// 復号化
esp_aes_context ctx;
esp_aes_init( &ctx );
esp_aes_setkey( &ctx, key, 256 );
int len = ( ( strlen(encrypted) + 15 ) / 16 ) * 16;
esp_aes_crypt_cbc( &ctx, ESP_AES_DECRYPT, len, iv, (uint8_t*)encrypted, (uint8_t*)plaintext );
esp_aes_free( &ctx );
}
// テキストダンプ
void dumpText(char *text ) {
// ダンプ
for ( int i = 0; i < 512; i++ ) {
if ( text[i] == 0 ) {
break;
}
// Serial.printf( "%02x[%c]%c", text[i], (text[i] > 31) ? text[i] : ' ', ((i & 0xf) != 0xf) ? ' ' : '\n' );
Serial.printf( "%02x ", text[i]);
}
Serial.printf( "\n" );
}
void dumpTextstr(char *text ) {
// ダンプ
for ( int i = 0; i < 512; i++ ) {
if ( text[i] == 0 ) {
break;
}
// Serial.printf( "%02x[%c]%c", text[i], (text[i] > 31) ? text[i] : ' ', ((i & 0xf) != 0xf) ? ' ' : '\n' );
Serial.printf( "%c", text[i]);
}
Serial.printf( "\n" );
}
void setup() {
Serial.begin(115200);
delay(1000); // Serial初期化待ち
// 暗号化キー
// uint8_t key[32];
// memset( key, 0, sizeof( key ) );
// aktio 61 6b 74 69 6f
// static uint8_t key[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x61, 0x6b, 0x74, 0x69, 0x6f,
// };
static uint8_t key[32] = { 0x61, 0x6b, 0x74, 0x69, 0x6f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 暗号化ベクトル
// uint8_t iv[16];
// memset( iv, 0, sizeof( iv ) );
static uint8_t iv[32] = { 0x32, 0x30, 0x32, 0x32, 0x30, 0x39, 0x30, 0x31,
0x41, 0x4b, 0x54, 0x49, 0x4f, 0x4b, 0x45, 0x59,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// テキスト一時領域
char plaintext[512];
char encrypted[512];
// 0クリア
memset( plaintext, 0, sizeof( plaintext ) );
memset( encrypted, 0, sizeof( encrypted ) );
// 平文セット
strcpy( plaintext, "PA123456755,0,20221007080000" );
// 暗号化
encodeAes(key, iv, plaintext, encrypted);
Serial.println("暗号化");
dumpText(encrypted);
base64encode(encrypted);
// 念の為0クリア
memset( plaintext, 0, sizeof( plaintext ) );
// 復号化
decodeAes(key, iv, plaintext, encrypted);
Serial.println("復号化");
dumpText(plaintext);
dumpTextstr(plaintext);
Serial.println("QRコード入力→復号化");
Serial.print(qr_decode("wkqcENHVjYF3Z7WyYzuH03Dtj7A4JIRGieF3vp5dMSw="));
Serial.println("eol");
// Serial.println("\n暗号入力");
// String aktio_enc = "wkqcENHVjYF3Z7WyYzuH03Dtj7A4JIRGieF3vp5dMSw=";
// Serial.println(aktio_enc);
// int str_len = aktio_enc.length() + 1;
// char char_array[str_len];
// aktio_enc.toCharArray(char_array, str_len);
// Serial.println("base64デコード");
// base64decode(char_array);
// // 念の為0クリア
// memset( plaintext, 0, sizeof( plaintext ) );
// memset( encrypted, 0, sizeof( encrypted ) );
// uint8_t raw[BASE64::decodeLength(char_array)];
// BASE64::decode(char_array, raw);
// for (int i = 0; i < BASE64::decodeLength(char_array); i++) {
// Serial.printf("%02x ", raw[i]);
// encrypted[i] = (char)raw[i];
// }
// Serial.println();
// // decodeAes(key, iv, plaintext, (char *)raw);
// decodeAes(key, iv, plaintext, encrypted);
// Serial.println("復号化");
// // dumpText(plaintext);
// dumpTextstr(plaintext);
}
void base64encode(char *rawData) {
// const char* rawData = "foobar";
size_t rawLength = strlen(rawData);
char encoded[BASE64::encodeLength(rawLength)];
BASE64::encode((const uint8_t*)rawData, rawLength, encoded);
Serial.println(encoded);
base64decode(encoded);
}
void base64decode(char *encoded) {
// const char* encoded = "Zm9vYmFy";
uint8_t raw[BASE64::decodeLength(encoded)];
BASE64::decode(encoded, raw);
// Serial.println((char*)raw);
for ( int i = 0; i < sizeof raw; i++ ) {
if ( raw[i] == 0 ) {
break;
}
// Serial.printf( "%02x[%c]%c", text[i], (text[i] > 31) ? text[i] : ' ', ((i & 0xf) != 0xf) ? ' ' : '\n' );
Serial.printf( "%02x ", raw[i]);
}
Serial.printf( "\n" );
}
String qr_decode(String encrypted_code){
static uint8_t key[32] = { 0x61, 0x6b, 0x74, 0x69, 0x6f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 暗号化ベクトル
// uint8_t iv[16];
// memset( iv, 0, sizeof( iv ) );
static uint8_t iv[32] = { 0x32, 0x30, 0x32, 0x32, 0x30, 0x39, 0x30, 0x31,
0x41, 0x4b, 0x54, 0x49, 0x4f, 0x4b, 0x45, 0x59,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// テキスト一時領域
char plaintext[512];
char encrypted[512];
// 0クリア
memset( plaintext, 0, sizeof( plaintext ) );
memset( encrypted, 0, sizeof( encrypted ) );
// Serial.println("\n暗号入力");
String aktio_enc = encrypted_code;
// Serial.println(aktio_enc);
int str_len = aktio_enc.length() + 1;
char char_array[str_len];
aktio_enc.toCharArray(char_array, str_len);
// Serial.println("base64デコード");
uint8_t raw[BASE64::decodeLength(char_array)];
BASE64::decode(char_array, raw);
for (int i = 0; i < BASE64::decodeLength(char_array); i++) {
// Serial.printf("%02x ", raw[i]);
encrypted[i] = (char)raw[i];
}
// Serial.println();
decodeAes(key, iv, plaintext, encrypted);
// Serial.println("復号化");
dumpTextstr(plaintext);
return String(plaintext);
}
void loop() {
}