這個問題是從 Arduino Stack Exchange遷移而來的,因為它可以在 Stack Overflow 上得到回答。 昨天遷移 。
我正在開發一個專案,以寫入和讀取 TP Link / Kaza 電源板或智能插頭。
發送的資料是經過“自動密鑰加密”的加密 json。
到目前為止,我已經能夠轉換一個打字稿加密函式并且效果很好。我得到了預期的結果。但是,我需要在我的加密資料中添加一個“標題”。該資料是 3 個空位元組,后跟一個位元組,該位元組是加密位元組長度的度量。
打字稿示例有這段代碼可以“使用標題加密”,但是,我在嘗試將其轉換為可用的東西時遇到了一些困難。有人可以在路上輕推我嗎?
首先是兩個打字稿功能:(借自https://github.com/plasticrake/tplink-smarthome-crypto/blob/master/src/index.ts)
/**
* Encrypts input where each byte is XOR'd with the previous encrypted byte.
*
* @param input - Data to encrypt
* @param firstKey - Value to XOR first byte of input
* @returns encrypted buffer
*/
export function encrypt(input: Buffer | string, firstKey = 0xab): Buffer {
const buf = Buffer.from(input);
let key = firstKey;
for (let i = 0; i < buf.length; i = 1) {
// eslint-disable-next-line no-bitwise
buf[i] ^= key;
key = buf[i];
}
return buf;
}
/**
* Encrypts input that has a 4 byte big-endian length header;
* each byte is XOR'd with the previous encrypted byte.
*
* @param input - Data to encrypt
* @param firstKey - Value to XOR first byte of input
* @returns encrypted buffer with header
*/
export function encryptWithHeader(
input: Buffer | string,
firstKey = 0xab
): Buffer {
const msgBuf = encrypt(input, firstKey);
const outBuf = Buffer.alloc(msgBuf.length 4);
outBuf.writeUInt32BE(msgBuf.length, 0);
msgBuf.copy(outBuf, 4);
return outBuf;
}
其次是我目前所擁有的。
// This part works well and produces the expected results
String encrypt(String input)
{
int16_t firstKey = 0xab;
String buf;
int key;
int i;
buf = input;
key = firstKey;
i = 0;
for (;i < buf.length();(i = i 1))
{
buf[i] ^= key;
key = buf[i];
}
return buf;
}
// This does not function yet, as I'm pretty lost..
// This was orginally converted from typescript with https://andrei-markeev.github.io/ts2c/
// I started work on converting this, but ran into errors I don't know how to solve.
String encryptWithHeader(String input){
String msgBuf;
String outBuf;
int16_t firstKey = 0xab;
char * null = NULL;
msgBuf = encrypt(input);
outBuf = msgBuf.length() 1;
//this is where I got lost...
assert(null != NULL);
null[0] = '\0';
strncat(null, outBuf, msgBuf.length());
str_int16_t_cat(null, 4);
outBuf = msgBuf 4
return outBuf;
}
最后,資料:
//this is the unencrypted json
String offMsg = "{\"system\":{\"set_relay_state\":{\"state\":0}}}";
//current encrypt function produces:
d0f281f88bff9af7d5ef94b6c5a0d48bf99cf091e8b7c4b0d1a5c0e2d8a381f286e793f6d4eedea3dea3
//the working "withheaders" should produce:
00002ad0f281f88bff9af7d5ef94b6c5a0d48bf99cf091e8b7c4b0d1a5c0e2d8a381f286e793f6d4eedea3dea3
誠然,我的 C/C 能力非常有限,我可以拼寫 typescript,僅此而已。我在 PHP 方面有著非常廣泛的歷史。一樣有用。所以,我了解資料結構的基礎知識等等,但我正在冒險進入我從未涉足過的領域。任何幫助將不勝感激。
uj5u.com熱心網友回復:
看起來加密相當簡單:將當前字符與密鑰異或寫入緩沖區,并使新寫入的字符成為新密鑰。看起來“withHeaders”版本將加密字串的長度作為 4 位元組整數添加到緩沖區的開頭。我認為分配一個字符陣列并將該陣列傳遞給一個將結果寫入該緩沖區的函式可能更容易。例如:
void encryptWithHeader(byte buffer[], int bufferLength, byte key, String message) {
int i;
uint32_t messageLength = message.length();
Serial.println(message);
Serial.println(message.length());
// check that we won't overrun the buffer
if ( messageLength 5 < bufferLength) {
buffer[0] = messageLength >> 24 & 0xFF;
buffer[1] = messageLength >> 16 & 0xFF;
buffer[2] = messageLength >> 8 & 0xFF;
buffer[3] = messageLength & 0xFF;
for (i = 0; i < messageLength; i ) {
buffer[i 4] = message[i] ^ key;
key = buffer[i 4];
}
}
else { // we would have overrun the buffer
Serial.println("not enough room in buffer for message");
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
byte theBuffer[64];
int i;
String offMsg = "{\"system\":{\"set_relay_state\":{\"state\":0}}}";
encryptWithHeader(theBuffer, 64, 0xab, offMsg);
// now print it out to check
for (i = 0; i < offMsg.length() 4; i ) {
if (theBuffer[i] < 0x10) // adds an extra zero if a byte prints as on1y 1 char
Serial.print("0");
Serial.print(theBuffer[i], HEX);
}
while (true)
;
}
如果要將字符緩沖區發送到遠程設備,可以一次發送一個位元組:
for (i = 0; i < offMsg.length() 4; i )
Serial.write(theBuffer[i]);
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/443568.html
