encrypting AES128-CBC on mbed microcontroller(c++) and decrypting AES128-CBC in nodejs
当我尝试在nodejs端解密字符串时,我收到"错误:错误:06065064:数字信封例程:EVP_DecryptFinal_ex:不良解密"。
我确实知道,为了提高安全性,我应该使用随机IV并始终为每次新加密更改IV,并且还应该实施身份验证,但是为了理解这一点并解决"不良解密"问题,我会坚持一些简单。一旦可以在mbed和nodejs上进行加密和解密,我将实现随机/更改IV和HMAC以增强安全性。
我想在mbed端加密传感器数据并在nodejs中解密传感器数据,但是,当尝试在nodejs端解密数据时,我收到"错误的解密"错误。如何解决"不良解密"错误?
mbed加密数据:
D90E1518FF2E5D79D6F848BCB4A49BCAE3ADDC6F1D6E04265613968CFF242855C10C619C8E281A33DA690039274AA65ECAFA05631C7BB38815442E780E27E34F2B6C4B9FE1B18678077227A93B43A93B43A93B43A43B43A43B43A43B43A43B43A43B43A43B43A43B3A54B3A54B3A54A7B3A7B3A7B3B3B3E3B3D3D3B3D3B3D3D3B3D3D4E3B4A4A4A4A4A4A4A4A4A4B4A4B4A4B4A4E4A4E8A4E1571
mbed C ++代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #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 ", 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(" JSON Char array"); for(char i=0; i<s.size(); i++) { if(i%16==0) pc.printf(" "); pc.printf("%.2X",s[i]); } AES myAES(AES_128, myKEY, myIV, CBC_MODE); // specify all params, look at BlockCipher.h for modes pc.printf(" First run "); myAES.encrypt(a,a,0x80); // same in and out buffer can be used pc.printf(" Encrypted"); for(char i=0; i<0x80; i++) { //if(i%16==0) pc.printf(" "); pc.printf("%.2X",a[i]); } pc.printf(" Decrypted again"); myAES.decrypt(a,a,0x80); for(char i=0; i<0x80; i++) { //if(i%16==0) pc.printf(" "); pc.printf("%.2X",a[i]); } } |
nodejs代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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); |
更新:
我将C ++加密/未加密的数据发送到我的串行终端,以查看数据是什么样的:
json:
{"Data1":["Result",5.50],"Data2":["Result",700],"Data3":["Result",65.70]}JSON Char array 7B224461746131223A5B22526573756C
74222C352E35305D2C22446174613222 3A5B22526573756C74222C3730305D2C
224461746133223A5B22526573756C74 222C36352E37305D7DFirst run
Encrypted
D90E1518FF2E5D79D6F848BCB4A49BCAE3ADDC6F1D6E04265613968CFF242855C10C619C8E281A33DA690039274AA65ECAFA05631C7BB38815442E780E27E34F2B6C4B9FE1B18678077227A05ACB233D8B8A81412E584A6ECAD10397FCF36072B043F93D67B63678A5D385B402D88AF99A62E12413E7BBFDB920B51F732C0933Decrypted again
7B224461746131223A5B22526573756C74222C352E35305D2C224461746132223A5B22526573756C74222C3730305D2C224461746133223A5B22526573756C74222C36352E37305D7D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
您的消息未填充,但是Node的解密程序需要输入的PKCS#7填充,如果找不到,则会失败。 通过调用
1 2 3 4 5 6 7 8 | 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; } |