2015-02-24 148 views
0

當我嘗試解密nodejs端的字符串時,收到「Error:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt」 。加密mbed微控制器(C++)上的AES128-CBC並解密nodejs中的AES128-CBC

我知道更好的安全性我應該使用一個隨機的IV,並且總是爲每一個新的加密改變IV,我也應該實現身份驗證,但爲了理解這個並且解決「壞解密」問題,我將堅持一些簡單的事情。一旦我可以在mbed和nodejs上進行加密和解密,我將實現隨機/改變IV和HMAC以增強安全性。

我想加密mbed端的傳感器數據並解密nodejs中的傳感器數據,但是當嘗試解密nodejs端的數據時,我收到「bad decrypt」錯誤。我該如何解決「壞解密」錯誤?

mbed加密數據:
D90E1518FF2E5D79D6F848BCB4A49BCAE3ADDC6F1D6E04265613968CFF242855C10C619C8E281A33DA690039274AA65ECAFA05631C7BB38815442E780E27E34F2B6C4B9FE1B18678077227A05ACB233D8B8A81412E584A6ECAD10397FCF36072B043F93D67B63678A5D385B402D88AF99A62E12413E7BBFDB920B51F732C0933

mbed C++代碼:

#include "mbed.h" 
#include "Crypto.h" 
#include "MbedJSONValue.h" 
#include "LinearTempSensor.h" 
#include "TimeUtilities.h" 
#include <string> 

Serial pc(USBTX, USBRX); 

RealTimeClock rtc; 

LinearTempSensor sensor(p20, 1000, LinearTempSensor::MCP9701); 

//unsigned char myKEY[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,}; 
//unsigned char myIV[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, }; 
unsigned char myKEY[16] = { 'm', 'n', 'b', 'v', 'c', 'x', 'z', 'l', 'k', 'j', 'h', 'g', 'f', 'd', 's', 'a' }; 
unsigned char myIV[16] = { 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'p', 'o', 'i', 'u', 'y', 't', 'r' }; 

unsigned char a[0x80] = { }; 

float Vout, Tav, To; 

int main() 
{ 
    pc.baud(115200); 

    MbedJSONValue sensorResults; 
    std::string s; 

    //Create JSON 
    sensorResults["Data1"][0] = "Result"; 
    sensorResults["Data1"][1] = 5.5; 
    sensorResults["Data2"][0] = "Result"; 
    sensorResults["Data2"][1] = 700; 
    sensorResults["Data3"][0] = "Result"; 
    sensorResults["Data3"][1] = 65.7; 

    Vout = sensor.Sense();   // Sample data (read sensor) 
    Tav = sensor.GetAverageTemp(); // Calculate average temperature from N samples 
    To = sensor.GetLatestTemp(); // Calculate temperature from the latest sample 

    //Serialize JSON 
    s = sensorResults.serialize(); 
    //sl = s.size(); 

    //Print JSON string 
    pc.printf("json: %s\r\n", s.c_str()); 

    //Convert JSON string to a char array to encrypt 
    //char *a=new char[s.size()+1]; 
    a[s.size()]=0; 
    memcpy(a,s.c_str(),s.size()); 

    //Print the char array to serial terminal 
    pc.printf("\r\nJSON Char array"); 

    for(char i=0; i<s.size(); i++) 
    { 
     if(i%16==0) pc.printf("\r\n"); 
     pc.printf("%.2X",s[i]); 
    } 

    AES myAES(AES_128, myKEY, myIV, CBC_MODE); // specify all params, look at BlockCipher.h for modes 
    pc.printf("\r\n\r\nFirst run\r\n"); 
    myAES.encrypt(a,a,0x80); // same in and out buffer can be used 
    pc.printf("\r\nEncrypted"); 
    for(char i=0; i<0x80; i++) 
    { 
     //if(i%16==0) pc.printf("\r\n"); 
     pc.printf("%.2X",a[i]); 
    } 

    pc.printf("\r\nDecrypted again"); 
    myAES.decrypt(a,a,0x80); 
    for(char i=0; i<0x80; i++) 
    { 
     //if(i%16==0) pc.printf("\r\n"); 
     pc.printf("%.2X",a[i]); 
    } 

} 

代碼的NodeJS:

var crypto = require("crypto") 

function encrypt(key, data, iv) { 
     var cipher = crypto.createCipheriv('aes-128-cbc', key, iv); 
     var crypted = cipher.update(text, 'utf-8', 'hex'); 
     crypted += cipher.final('hex'); 

     return crypted; 
} 

function decrypt(key, data, iv) { 
     var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv); 
     var decrypted = decipher.update(data, 'hex', 'utf-8'); 
     decrypted += decipher.final('utf-8'); 

     return decrypted; 
} 

var key = "mnbvcxzlkjhgfdsa"; 
var iv = "asdfghjklpoiuytr"; 

var text = "{\"Data1\":[\"Result\",5.50],\"Data2\":[\"Result\",700],\"Data3\":[\"Result\",65.70]}"; 
console.log("Original Text: " + text); 

var endata = "D90E1518FF2E5D79D6F848BCB4A49BCAE3ADDC6F1D6E04265613968CFF242855C10C619C8E281A33DA690039274AA65ECAFA05631C7BB38815442E780E27E34F2B6C4B9FE1B18678077227A05ACB233D8B8A81412E584A6ECAD10397FCF36072B043F93D67B63678A5D385B402D88AF99A62E12413E7BBFDB920B51F732C0933"; 
var decryptedText = decrypt(key, endata, iv); 
console.log("Decrypted Text: " + decryptedText); 

UPDATE:
我把C++加密/未加密的數據,以我的串口終端看到的數據是什麼樣子:

json: {"Data1":["Result",5.50],"Data2":["Result",700],"Data3":["Result",65.70]}

JSON Char array 7B224461746131223A5B22526573756C 74222C352E35305D2C22446174613222 3A5B22526573756C74222C3730305D2C 224461746133223A5B22526573756C74 222C36352E37305D7D

First run

Encrypted D90E1518FF2E5D79D6F848BCB4A49BCAE3ADDC6F1D6E04265613968CFF242855C10C619C8E281A33DA690039274AA65ECAFA05631C7BB38815442E780E27E34F2B6C4B9FE1B18678077227A05ACB233D8B8A81412E584A6ECAD10397FCF36072B043F93D67B63678A5D385B402D88AF99A62E12413E7BBFDB920B51F732C0933

Decrypted again 7B224461746131223A5B22526573756C74222C352E35305D2C224461746132223A5B22526573756C74222C3730305D2C224461746133223A5B22526573756C74222C36352E37305D7D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

+0

@StefanoSanfilippo不,Node.js無法正常工作。 Nodejs拋出「壞解密」錯誤。 – dottedquad 2015-02-24 19:44:30

+0

因此'endata'就是你的C++代碼發送給JS的東西,'text'就是輸入的內容,對吧? – 2015-02-24 19:52:20

+0

@StefanoSanfilippo是的,endata是我的C++代碼發送給JS的文本,文本是解密數據的外觀。我會更新我的帖子以顯示C++加密/未加密數據應該是什麼樣子。 – dottedquad 2015-02-24 19:57:48

回答

2

你的消息不填充,但節點的慾海預計輸入的PKCS#7 padding當沒有找到時失敗。通過致電Decipher.setAutoPadding()禁用填充:

function decrypt(key, data, iv) { 
     var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv); 
     decipher.setAutoPadding(false); 
     var decrypted = decipher.update(data, 'hex', 'utf-8'); 
     decrypted += decipher.final('utf-8'); 

     return decrypted; 
} 
+0

我仍然收到 「壞解密」 錯誤 'VAR endata =新的緩衝區( 「D90E1518FF2E5D79D6F848BCB4A49BCAE3ADDC6F1D6E04265613968CFF242855C10C619C8E281A33DA690039274AA65ECAFA05631C7BB38815442E780E27E34F2B6C4B9FE1B18678077227A05ACB233D8B8A81412E584A6ECAD10397FCF36072B043F93D67B63678A5D385B402D88AF99A62E12413E7BBFDB920B51F732C0933」, 「六角」); // var endatabuffer = new Buffer(endata,「hex」); var decryptedText = decrypt(key,endata,iv); console.log(「Decrypted Text:」+ decryptedText);' – dottedquad 2015-02-24 20:18:32

+0

我拷貝了很長的巨大字符串。看起來這個字符串被移動了,所以它可以放入註釋區域而不必滾動。 [這是我的IDE的圖像] http://imagizer.imageshack.us/a/img661/8391/HiIq9B.png – dottedquad 2015-02-24 20:59:34

+1

是...經過一些更多的檢查,看起來問題是填充,實際的輸入是好的,你不需要緩衝區(我應該閱讀'更新'文檔)。 – 2015-02-24 21:51:54