2017-01-29 26 views
0

私は復号化と復号化を間違ってやっていると確信していますが、正確にはわかりません。ESP8266 AESの暗号化 - 復号化

#include "AES.h" 
#include "Base64.h" 

AES aes; 

// Our AES key. Note that is the same that is used on the Node-Js side but as hex bytes. 
byte key[] = {0x7e, 0x4e, 0x42, 0x38, 0x43, 0x63, 0x4f, 0x4c, 0x23, 0x4a, 0x21, 0x48, 0x3f, 0x7c, 0x59, 0x72}; 

// The unitialized Initialization vector 
byte iv[N_BLOCK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 

// Our message to encrypt. Static for this example. 
String msg = "{\"data\":{\"value\":300}, \"SEQN\":700 , \"msg\":\"IT WORKS!!\" }"; 

uint8_t generate_random_unit8() 
{ 
    uint8_t really_random = *(volatile uint8_t *)0x3FF20E44; 
    return really_random; 
} 

// Generate a random initialization vector 
void generate_iv(byte *vector) 
{ 
    for (int i = 0; i < N_BLOCK; i++) 
    { 
    vector[i] = (byte)generate_random_unit8(); 
    } 
} 

void encrypt() 
{ 
    char b64data[200]; 
    byte cipher[1000]; 
    byte iv[N_BLOCK]; 

    generate_iv(iv); 

    base64_encode(b64data, (char *)iv, N_BLOCK); 
    String IV_base64 = String(b64data); 
    Serial.println(" IV b64: " + IV_base64); 

    int b64len = base64_encode(b64data, (char *)msg.c_str(), msg.length()); 

    Serial.println(" The lenght is: " + String(b64len)); 

    // Encrypt! With AES128, our key and IV, CBC and pkcs7 padding 
    aes.do_aes_encrypt((byte *)b64data, b64len, cipher, key, 128, iv); 

    Serial.println("Cipher size: " + String(aes.get_size())); 

    base64_encode(b64data, (char *)cipher, aes.get_size()); 
    Serial.println("Encrypted data in base64: " + String(b64data)); 

    decrypt(b64data, IV_base64, aes.get_size()); 
} 

void decrypt(String b64data, String IV_base64, int size) 
{ 
    char data_decoded[200]; 
    char iv_decoded[200]; 
    byte out[200]; 
    char temp[200]; 
    b64data.toCharArray(temp, 200); 
    base64_decode(data_decoded, temp, b64data.length()); 
    IV_base64.toCharArray(temp, 200); 
    base64_decode(iv_decoded, temp, IV_base64.length()); 
    aes.do_aes_decrypt((byte *)data_decoded, size, out, key, 128, (byte *)iv_decoded); 
    char message[msg.length()]; 
    base64_decode(message, (char *)out, b64data.length()); 
    printf("Out %s \n", message); 
} 

void setup_aes() 
{ 
    aes.set_key(key, sizeof(key)); // Get the globally defined key 
} 

void setup() 
{ 
    Serial.begin(115200); 
} 

void loop() 
{ 
    encrypt(); 
    delay(1000); 
} 

デコードされたメッセージは{"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!!"である必要があります。しかし、私は{"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!!" }�������������������������を得ています。私はcharの長さが正しくないと思いますか?

+0

リサイクラが指摘するように、返される文字列にはターミネータがありません。ただし、charメッセージ[msg.length()+ 1]でデコードされたバッファに追加することはできます。解読の際に。しかし、あなたのプログラムは非常に混乱していることがわかりました。なぜなら、文字列に変換する必要があるのはなぜですか?そして最も重要なのは、なぜplaintextをbase64に変換したのですか? – frarugi87

+0

'generate_random_unit8'はどのようにランダムなのですか? – dandavis

+0

はい、このコード全体が犯されてしまいます.PoCのためにブログからコピーしました。 –

答えて

1

エンコードする場合、\ 0で文字列をファイナライズする必要があります。デコードされたデータでは、\ 0もそこにあり、printfは\ 0で正しく終わることができます。

修正は int b64len = base64_encode(b64data, (char *)msg.c_str(), msg.length()+1); になります。暗黙の\ 0バイトが確実に含まれます。コンパイラはこれをmsg文字列に自動的に追加します。

符号化されたデータの長さ - - 1

少なくとものPoC作品

0

私は最終的に間違っていたものを見つけ..

base64_decode(message, (char *)out, b64data.length());

base64_decode(message, (char *)out, 75);でなければなりません。

0

私は最近、自分自身で同じ問題を抱えていましたが、これを理解するのに数時間を費やしました。 Ivanov、符号化されたデータの長さについては良い点があります。主な問題は、基本的にAES暗号化機能が追加の埋め込みを作成し、復号化機能がそれを取り除くことができない場合です。

これは、文字列のNULL終了や終端文字がないという事実とは関係ありません。この問題は、実際に解読された文字列から最後の5詰めを省略することで解決されます。

これは実際には最後から5文字を省略するだけではありません。私が知っているように、ぎこちないやパディングの量は、元のJSONの長さによって異なるので、JSON文字列の終わりを検出することによって文字列をトリミングする方が意味があります。

参考のために私の(更新された)作業コードを提供しています。私はこれがまたこの問題を抱えている人に役立つことを願っていますあなたのプロジェクトに幸運を祈る!

#include "AES.h" 
#include "Base64.h" 

AES aes; 

// Our AES key. Same in NodeJS but in hex bytes 
byte key[] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; 
// The unitialized Initialization vector (16-bit) 
byte iv[N_BLOCK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 

// NodeMCU side raw message 
String msg = "{\"x\":10, \"y\":20, \"z\":30 \"lamp_stat\":\"ON This is a sentence. Testing testing testing\"}"; 

uint8_t generate_random_unit8() 
{ 
    uint8_t really_random = *(volatile uint8_t *)0x3FF20E44; 
    return really_random; 
} 

// Generate a random initialization vector 
void generate_iv(byte *vector) 
{ 
    for (int i = 0; i < N_BLOCK; i++) 
    { 
    vector[i] = (byte)generate_random_unit8(); 
    } 
} 

void encrypt() 
{ 
    char b64data[200]; 
    byte cipher[1000]; 
    byte iv[N_BLOCK]; 

    generate_iv(iv); 

    base64_encode(b64data, (char *)iv, N_BLOCK); 
    String IV_base64 = String(b64data); 
    Serial.println(" IV b64: " + IV_base64); 

    int b64len = base64_encode(b64data, (char *)msg.c_str(), msg.length()); 

    Serial.println(" The lenght is: " + String(b64len)); 

    // Encrypt! With AES128, our key and IV, CBC and pkcs7 padding 
    aes.do_aes_encrypt((byte *)b64data, b64len, cipher, key, 128, iv); 

    Serial.println("Cipher size: " + String(aes.get_size())); 

    base64_encode(b64data, (char *)cipher, aes.get_size()); 
    Serial.println("Encrypted data in base64: " + String(b64data)); 

    //decrypt(b64data, IV_base64, aes.get_size()); 
} 

void decrypt(String b64data, String IV_base64, int lsize) 
{ 
    char data_decoded[300]; 
    char iv_decoded[300]; 
    byte out[300]; 
    char temp[300]; 
    b64data.toCharArray(temp, 300); 
    base64_decode(data_decoded, temp, b64data.length()); 
    IV_base64.toCharArray(temp, 300); 
    base64_decode(iv_decoded, temp, IV_base64.length()); 
    aes.do_aes_decrypt((byte *)data_decoded, lsize, out, key, 128, (byte *)iv_decoded); 
    char message[msg.length()]; 
    base64_decode(message, (char *)out, aes.get_size()); 
    for (int i = 0; i < aes.get_size(); i++) 
    { 
    char curChar = (char)message[i]; 
    if (curChar != '}') 
     temp[i] = curChar; 
    else 
    { 
     temp[i] = curChar; 
     temp[i+1] = '\0'; 
     break; 
    } 
    } 
    String result = String((char *)temp); 
    Serial.println(result); 
} 

void setup_aes() 
{ 
    aes.set_key(key, sizeof(key)); // Get the globally defined key 
} 

void setup() 
{ 
    Serial.begin(115200); 

} 

void loop() 
{ 
    encrypt(); 
    decrypt("ipYk12VCYyD+aJ7KL7lO8L5zOq71XvsLzp650gKBFgQor7GHs98QpQSjQOZdhCwggq2Ehf4nVNwTeK3VjtqMVJRGBw9YViARXCTOGqctjFc=", "+eNzSlRRPi0YZhrp5ctpnA==", 83); 
    delay(8000); 
}