Base64 编码后的 DES 加密给出不同的结果

问题描述

我有一个 Java BMS 应用程序,其中包含在 RPi 上运行的 Java 客户端。但是,我喜欢将 Arduino 单元添加到系统中,因为它们更简单,但最好使用相同的通信协议。

我使用 DES 加密一个 JSON,然后使用 Base64 对其进行编码。

    DESKeySpec keySpec = new DESKeySpec(encryptionKey.getBytes("UTF8"));
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey key = keyFactory.generateSecret(keySpec);
    byte[] cleartext = data.getBytes("UTF8");
    Cipher cipher = Cipher.getInstance("DES"); // cipher is not thread safe
    cipher.init(Cipher.ENCRYPT_MODE,key);
    byte[] finalByte = cipher.doFinal(cleartext);
    return Base64.encodeBase64String(finalByte);

对于以下 JSON,这将导致字节(作为十六进制):

json: {"result":"SUCCESS","message":"(none)","actions":[{"action":"campAlarm","value":"false"},{"action":"warningBeep",{"action":"gpio_21","value":0}]}
Encrypted: 1e64fd8c074b2eda044f2ed820dab06949e5a2c5602918b13779e906c2733c1719965a456e2127fef0c910cbbbfcd137c535c9423cc14e7e757ddbe9f74ea307d7584eed404e31ff4cb069c40b2464eff5a6705666900a5706950b87df995e8252ed2dfb1070287c080a3527b3c40a2749c2982d033279b827cde81829d2a8d7568808caa6604a32ef41fe9b1a2fdbd3e79d5107938e6b179100c7f542cfe8cb433750ea38954bd9
Base64 encoded: HmT9jAdLLtoETy7YINqwaUnlosVgKRixN3npBsJzPBcZllpFbiEn/vDJEMu7/NE3xTXJQjzBTn51fdvp906jB9dYTu1ATjH/TLBpxAskZO/1pnBWZpAKVwaVC4ffmV6CUu0t+xBwKHwICjUns8QKJ0nCmC0DMnm4J83oGCnSqNdWiAjKpmBKMu9B/psaL9vT551RB5OOaxeRAMf1Qs/oy0M3UOo4lUvZ

但是,我在处理这个特定的 json 字符串时遇到了困难(并非所有情况都会发生)。 Base64编码前的服务器加密数据中有额外的零(读取HEX),在Arduino上用Base64解码后没有(结果是带有Base64编码数据的字符串):

  char encoded[result.length()];
  result.tochararray(encoded,result.length());

  // Convert back.
  int decodedLength = Base64.decodedLength(encoded,sizeof(encoded));
  char decodedChar[decodedLength];
  Base64.decode(decodedChar,encoded,sizeof(encoded));
  Serial.print("Decoded: "); des.printArray((byte*) decodedChar,decodedLength);
  for (int i = 0; i < decodedLength; i += 8) {
    byte intermitInput[8];
    for (int j = 0; j < 8; j++) {
      intermitInput[j] = (byte) decodedChar[i + j];
    }
    Serial.print(i);Serial.print(" ");
    des.decrypt((byte*)decodedChar + i,intermitInput,(byte*)key); // Re-use the decodedChar array as it is already initiated (saving money)
  }
  Serial.println("Finished decription.");
  decodedChar[decodedLength] = '\0';
  Serial.print("Decripted: "); des.printArray((byte*) decodedChar,(int) sizeof(decodedChar));
  Serial.print("Decripted result:\t");
  Serial.println(decodedChar);

结果:

Base64 decoded: 1e64fd8c74b2eda44f2ed820dab06949e5a2c5602918b13779e96c2733c1719965a456e2127fef0c910cbbbfcd137c535c9423cc14e7e757ddbe9f74ea37d7584eed404e31ff4cb069c4b2464eff5a670566690a57695b87df995e8252ed2dfb1070287c8a3527b3c4a2749c2982d33279b827cde81829d2a8d756888caa6604a32ef41fe9b1a2fdbd3e79d517938e6b17910c7f542cfe8cb433750ea38954bbf
DES decrypted: 7b22726573756c74223a2253554343455353222c226d657373616765223a22286e6f6e6529222c2022616374696f6e73223a5b7b22616374696f6e223a2263616d70416c61726d222c2276616c7565223a2266616c7365227d2c7b22616374696f6e223a227761726e696e6742656570222c2276616c7565223a2266616c7365227d2c7b22616374696f6e223a226770696f5f3231222c2276616c7565223a30d8e9d029b7c75ed1
json:   {"result":"SUCCESS","value":0⸮⸮⸮)⸮⸮^⸮

我猜这是因为 Base64 解码后“缺少”“0”(在十六进制中),如果 json 关闭,则最后 8 个字符。这只是一个猜测,因为我不知道那些“0”十六进制“字符”丢失的原因。 (例如 1e64fd8c07 与 1e64fd8c7)

有人知道这是怎么发生的吗?有趣的是,除了最后一组 8 个字节之外,字符串被正确解密。该字符串为 163 个字符,因此在编码时进行填充。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)