suculent / thinx-aes-lib

AES wrapper for ESP8266/ESP32/Arduino/nRF5x
Other
117 stars 38 forks source link

Cant get the right number #44

Closed Saeedsaeb closed 3 years ago

Saeedsaeb commented 3 years ago

Hello again , i have replace version 2.2.0 with version 2.2.1 The simple example dose not work i am trying to convert some text to AES and read the Cipher to do some comparison . but the output is not the same , i cant fgureout where i went wrong this is the data i must be working on : this have been made by nodejs

input data = Hello World! padding: CMS key: d8402bd365a34b4d34729c3fa420818b iv: e7b9fec726e2e98252713a1495c636a8 enc: c1782bb6cff3b64578ec12d68989aa3d this is my code:

/* Simple buffer example for low-memory conditions (Arduino) */

#include "AESLib.h"

#define BAUD 9600

AESLib aesLib;

#define INPUT_BUFFER_LIMIT (128 + 1) // designed for Arduino UNO, not stress-tested anymore (this works with readBuffer[129])

unsigned char cleartext[INPUT_BUFFER_LIMIT] = {0}; // THIS IS INPUT BUFFER (FOR TEXT)
unsigned char ciphertext[2*INPUT_BUFFER_LIMIT] = {0}; // THIS IS OUTPUT BUFFER (FOR BASE64-ENCODED ENCRYPTED DATA)

unsigned char readBuffer[18] = "Hello World!";

// AES Encryption Key (same as in node-js example)
//byte aes_key[] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C };
byte aes_key[] = {0xd8 , 0x40 , 0x2b , 0xd3 , 0x65 , 0xa3 , 0x4b , 0x4d , 0x34 , 0x72 , 0x9c , 0x3f , 0xa4 , 0x20 , 0x81 , 0x8b };

// General initialization vector (same as in node-js example) (you must use your own IV's in production for full security!!!)
//byte aes_iv[N_BLOCK] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
byte aes_iv[N_BLOCK] = {0xe7 , 0xb9 , 0xfe , 0xc7 , 0x26 , 0xe2 , 0xe9 , 0x82 , 0x52 , 0x71 , 0x3a , 0x14 , 0x95 , 0xc6 , 0x36 , 0xa8};

// Generate IV (once)
void aes_init() {
//  aesLib.gen_iv(aes_iv);
  aesLib.set_paddingmode((paddingMode)0);
}

uint16_t encrypt_to_ciphertext(char * msg, uint16_t msgLen, byte iv[]) {
  Serial.println("Calling encrypt (string)...");
  // aesLib.get_cipher64_length(msgLen);
  int cipherlength = aesLib.encrypt((byte*)msg, msgLen, (char*)ciphertext, aes_key, sizeof(aes_key), iv);
                   // uint16_t encrypt(byte input[], uint16_t input_length, char * output, byte key[],int bits, byte my_iv[]);
  return cipherlength;
}

uint16_t decrypt_to_cleartext(byte msg[], uint16_t msgLen, byte iv[]) {
  Serial.print("Calling decrypt...; ");
  uint16_t dec_bytes = aesLib.decrypt(msg, msgLen, (char*)cleartext, aes_key, sizeof(aes_key), iv);
  Serial.print("Decrypted bytes: "); Serial.println(dec_bytes);
  return dec_bytes;
}

void setup() {
  Serial.begin(BAUD);
  Serial.setTimeout(60000);
  delay(2000);

  aes_init(); // generate random IV, should be called only once? causes crash if repeated...

}

/* non-blocking wait function */
void wait(unsigned long milliseconds) {
  unsigned long timeout = millis() + milliseconds;
  while (millis() < timeout) {
    yield();
  }
}

unsigned long loopcount = 0;

// Working IV buffer: Will be updated after encryption to follow up on next block.
// But we don't want/need that in this test, so we'll copy this over with enc_iv_to/enc_iv_from
// in each loop to keep the test at IV iteration 1. We could go further, but we'll get back to that later when needed.

// General initialization vector (same as in node-js example) (you must use your own IV's in production for full security!!!)
byte enc_iv[N_BLOCK] =      {0xe7 , 0xb9 , 0xfe , 0xc7 , 0x26 , 0xe2 , 0xe9 , 0x82 , 0x52 , 0x71 , 0x3a , 0x14 , 0x95 , 0xc6 , 0x36 , 0xa8};
byte enc_iv_to[N_BLOCK]   = {0xe7 , 0xb9 , 0xfe , 0xc7 , 0x26 , 0xe2 , 0xe9 , 0x82 , 0x52 , 0x71 , 0x3a , 0x14 , 0x95 , 0xc6 , 0x36 , 0xa8};
byte enc_iv_from[N_BLOCK] = {0xe7 , 0xb9 , 0xfe , 0xc7 , 0x26 , 0xe2 , 0xe9 , 0x82 , 0x52 , 0x71 , 0x3a , 0x14 , 0x95 , 0xc6 , 0x36 , 0xa8};

void loop() {

  Serial.print("readBuffer length: "); Serial.println(sizeof(readBuffer));

   // must not exceed INPUT_BUFFER_LIMIT bytes; may contain a newline
  sprintf((char*)cleartext, "%s", readBuffer);

  // Encrypt
  // iv_block gets written to, provide own fresh copy... so each iteration of encryption will be the same.
  uint16_t msgLen = sizeof(readBuffer);
  memcpy(enc_iv, enc_iv_to, sizeof(enc_iv_to));
  uint16_t encLen = encrypt_to_ciphertext((char*)cleartext, msgLen, enc_iv);
  Serial.print("Encrypted length = "); Serial.println(encLen );

 Serial.println("DATA CODED : " );
  for(int i=0; i<encLen;i++)
  {
    Serial.printf("%02X",ciphertext[i]);
  }
  Serial.println();
  Serial.println("DATA CODED END " );

  Serial.println("Encrypted. Decrypting..."); Serial.println(encLen ); Serial.flush();
  memcpy(enc_iv, enc_iv_from, sizeof(enc_iv_from));
  uint16_t decLen = decrypt_to_cleartext(ciphertext, encLen , enc_iv);
  Serial.print("Decrypted cleartext of length: "); Serial.println(decLen);
  Serial.print("Decrypted cleartext:\n"); Serial.println((char*)cleartext);

  if (strcmp((char*)readBuffer, (char*)cleartext) == 0) {
    Serial.println("Decrypted correctly.");
  } else {
    Serial.println("Decryption test failed.");
  }

  Serial.println("---");
  delay(3000);
}

this is the output :

---
readBuffer length: 18
Calling encrypt (string)...
Encrypted length = 44
DATA CODED : 
392F55513847625945743955484F32534F6F345065684D3445652F43713550446B3776455A4B51323537343D
DATA CODED END 
Encrypted. Decrypting...
44
Calling decrypt...; Decrypted bytes: 44
Decrypted cleartext of length: 44
Decrypted cleartext:
⸮#J⸮Ku⸮⸮͖⸮ϒ+Ty#2
ޚ⸮Ρ{⸮g⸮Ϋ
Decryption test failed.
---

and this is the output of simple example without any change (as is):

readBuffer length: 18
Calling encrypt (string)...
Encrypted length = 44
Encrypted. Decrypting...
44
Calling decrypt...; Decrypted bytes: 44
Decrypted cleartext of length: 44
Decrypted cleartext:
#⸮C⸮⸮䡯:=⸮⸮⸮.Qiש⸮⸮⸮L⸮cak⸮⸮F⸮
Decryption test failed.

The example dose not work thanks

Saeedsaeb commented 3 years ago

Hello again , this is the output i got from kakopappa , the KEY and IV has been copied from the code i did with this library https://github.com/kakopappa/arduino-esp8266-aes-lib

Booting...
Let's encrypt:
 IV b64: 57n+xybi6YJScToUlcY2qA==

C1782BB6CFF3B64578EC12D68989AA3D

Encryption done!
Cipher size: 16
Encrypted data in base64: wXgrts/ztkV47BLWiYmqPQ==
Done...

the cipher is C1782BB6CFF3B64578EC12D68989AA3D wich is working fine , i dont know if know the library or not but this is my code in taht library , however i like to do this using this library , i put the codes so if i am wrong in a place u could tell me


#include "AES.h"
#include "base64.h"

AES aes;

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

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

void setup() {
    Serial.begin(115200);
    Serial.println("\nBooting...");  

    char b64data[200];
    byte cipher[1000];
    byte iv [N_BLOCK] ;

    Serial.println("Let's encrypt:");
    // Our AES key. Note that is the same that is used on the Node-Js side but as hex bytes.
//    byte key[] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C };
    byte key[] ={0xd8 , 0x40 , 0x2b , 0xd3 , 0x65 , 0xa3 , 0x4b , 0x4d , 0x34 , 0x72 , 0x9c , 0x3f , 0xa4 , 0x20 , 0x81 , 0x8b };
    // The unitialized Initialization vector
//    byte my_iv[N_BLOCK] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    byte my_iv[N_BLOCK] ={0xe7 , 0xb9 , 0xfe , 0xc7 , 0x26 , 0xe2 , 0xe9 , 0x82 , 0x52 , 0x71 , 0x3a , 0x14 , 0x95 , 0xc6 , 0x36 , 0xa8};

    // Our message to encrypt. Static for this example.
    char msg[] = "Hello World!";

    aes.set_key( key , sizeof(key));  // Get the globally defined key
//    gen_iv( my_iv );                  // Generate a random IV

    // Print the IV
    base64_encode( b64data, (char *)my_iv, N_BLOCK);
    Serial.println(" IV b64: " + String(b64data));

//    Serial.println(" Message: " + msg );

//    int b64len = base64_encode(b64data, (char *)msg.c_str(),msg.length());
//    Serial.println (" Message in B64: " + String(b64data) );
//    Serial.println (" The lenght is:  " + String(b64len) );

    // For sanity check purpose
    //base64_decode( decoded , b64data , b64len );
    //Serial.println("Decoded: " + String(decoded));

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

Serial.println();
Serial.println();
  for(int i=0;i<aes.get_size();i++)
  {
    Serial.printf("%X",cipher[i]);
  }
  Serial.println();
  Serial.println();
    Serial.println("Encryption done!");

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

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

    Serial.println("Done...");
}

void loop() {
  // put your main code here, to run repeatedly:

}
suculent commented 3 years ago

OK, so don't know why/how exactly but the encrypt function did accidentally include base64 conversion. It should not be there so I've removed it. After that change, the simple example forks as expected again.