2017-01-29 9 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

나는 최근에 나 자신과 같은 문제를 겪고 있었고 나는 이것을 알아 내려고 몇 시간을 보냈다. 이바노프, 당신은 인코딩 된 데이터의 길이에 대해 좋은 지적을 가지고 있습니다. 주요 문제는 기본적으로 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); 
}