mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[gree] Add support for ASC/GCM encryption (#16950)
* [gree] support for ASC/GCM encryption Signed-off-by: Zhivka Dimova <zhivka.dimova@myforest.net> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
ed9afe8fbe
commit
a6022133c4
@ -13,18 +13,22 @@
|
||||
package org.openhab.binding.gree.internal;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
import java.util.HexFormat;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.gree.internal.gson.GreeBaseDTO;
|
||||
|
||||
/**
|
||||
* The CryptoUtil class provides functionality for encrypting and decrypting
|
||||
@ -36,11 +40,68 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@NonNullByDefault
|
||||
public class GreeCryptoUtil {
|
||||
private static final String AES_KEY = "a3K8Bx%2r8Y7#xDh";
|
||||
private static final String GCM_KEY = "{yxAHAY_Lm6pbC/<";
|
||||
private static final String GCM_IV = "5440784449675a516c5e6313";
|
||||
private static final String GCM_ADD = "qualcomm-test";
|
||||
private static final int TAG_LENGTH = 16;
|
||||
|
||||
public enum EncryptionTypes {
|
||||
ECB,
|
||||
GCM
|
||||
};
|
||||
|
||||
public static byte[] getAESGeneralKeyByteArray() {
|
||||
return AES_KEY.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static byte[] getGCMGeneralKeyByteArray() {
|
||||
return GCM_KEY.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static byte[] getGeneralKeyByteArray(EncryptionTypes encType) {
|
||||
if (encType == EncryptionTypes.GCM) {
|
||||
return getGCMGeneralKeyByteArray();
|
||||
}
|
||||
return getAESGeneralKeyByteArray();
|
||||
}
|
||||
|
||||
public static byte[] getGCMIVByteArray() {
|
||||
return HexFormat.of().parseHex(GCM_IV);
|
||||
}
|
||||
|
||||
public static byte[] getGCMADDByteArray() {
|
||||
return GCM_ADD.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static <T extends GreeBaseDTO> EncryptionTypes getEncryptionType(T response) {
|
||||
return response.tag != null ? EncryptionTypes.GCM : EncryptionTypes.ECB;
|
||||
}
|
||||
|
||||
public static <T extends GreeBaseDTO> String decrypt(T response) throws GreeException {
|
||||
return decrypt(response, getEncryptionType(response));
|
||||
}
|
||||
|
||||
public static <T extends GreeBaseDTO> String decrypt(byte[] keyarray, T response) throws GreeException {
|
||||
return decrypt(keyarray, response, getEncryptionType(response));
|
||||
}
|
||||
|
||||
public static <T extends GreeBaseDTO> String decrypt(T response, EncryptionTypes encType) throws GreeException {
|
||||
if (encType == EncryptionTypes.GCM) {
|
||||
return decrypt(getGCMGeneralKeyByteArray(), response, encType);
|
||||
} else {
|
||||
return decrypt(getAESGeneralKeyByteArray(), response, encType);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends GreeBaseDTO> String decrypt(byte[] keyarray, T response, EncryptionTypes encType)
|
||||
throws GreeException {
|
||||
if (encType == EncryptionTypes.GCM) {
|
||||
return decryptGCMPack(keyarray, response.pack, response.tag);
|
||||
} else {
|
||||
return decryptPack(keyarray, response.pack);
|
||||
}
|
||||
}
|
||||
|
||||
public static String decryptPack(byte[] keyarray, String message) throws GreeException {
|
||||
try {
|
||||
Key key = new SecretKeySpec(keyarray, "AES");
|
||||
@ -58,6 +119,41 @@ public class GreeCryptoUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static String decryptGCMPack(byte[] keyBytes, String pack, String tag) throws GreeException {
|
||||
try {
|
||||
Key key = new SecretKeySpec(keyBytes, "AES");
|
||||
Base64.Decoder decoder = Base64.getDecoder();
|
||||
|
||||
byte[] packBytes = decoder.decode(pack);
|
||||
byte[] tagBytes = decoder.decode(tag);
|
||||
|
||||
byte[] messageBytes = new byte[packBytes.length + tagBytes.length];
|
||||
System.arraycopy(packBytes, 0, messageBytes, 0, packBytes.length);
|
||||
System.arraycopy(tagBytes, 0, messageBytes, packBytes.length, tagBytes.length);
|
||||
|
||||
Cipher gcmCipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, getGCMIVByteArray());
|
||||
gcmCipher.init(Cipher.DECRYPT_MODE, key, gcmParameterSpec);
|
||||
gcmCipher.updateAAD(getGCMADDByteArray());
|
||||
|
||||
byte[] bytePlainText = gcmCipher.doFinal(messageBytes);
|
||||
return new String(bytePlainText, StandardCharsets.UTF_8);
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | InvalidKeyException
|
||||
| IllegalBlockSizeException | InvalidAlgorithmParameterException ex) {
|
||||
throw new GreeException("GCM decryption of recieved data failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] encrypt(byte[] keyarray, String message, EncryptionTypes encType) throws GreeException {
|
||||
if (encType == EncryptionTypes.GCM) {
|
||||
return encryptGCMPack(keyarray, message);
|
||||
} else {
|
||||
String[] res = new String[1];
|
||||
res[0] = encryptPack(keyarray, message);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public static String encryptPack(byte[] keyarray, String message) throws GreeException {
|
||||
try {
|
||||
Key key = new SecretKeySpec(keyarray, "AES");
|
||||
@ -72,4 +168,32 @@ public class GreeCryptoUtil {
|
||||
throw new GreeException("Unable to encrypt outbound data", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] encryptGCMPack(byte[] keyarray, String message) throws GreeException {
|
||||
try {
|
||||
Key key = new SecretKeySpec(keyarray, "AES");
|
||||
|
||||
Cipher gcmCipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, getGCMIVByteArray());
|
||||
gcmCipher.init(Cipher.ENCRYPT_MODE, key, gcmParameterSpec);
|
||||
gcmCipher.updateAAD(getGCMADDByteArray());
|
||||
|
||||
byte[] encrypted = gcmCipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
int packLength = encrypted.length - TAG_LENGTH;
|
||||
byte[] pack = new byte[packLength];
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
System.arraycopy(encrypted, 0, pack, 0, packLength);
|
||||
System.arraycopy(encrypted, packLength, tag, 0, TAG_LENGTH);
|
||||
|
||||
Base64.Encoder encoder = Base64.getEncoder();
|
||||
String[] encryptedData = new String[2];
|
||||
encryptedData[0] = new String(encoder.encode(pack), StandardCharsets.UTF_8);
|
||||
encryptedData[1] = new String(encoder.encode(tag), StandardCharsets.UTF_8);
|
||||
return encryptedData;
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | InvalidKeyException
|
||||
| IllegalBlockSizeException | InvalidAlgorithmParameterException ex) {
|
||||
throw new GreeException("Unable to encrypt (gcm) outbound data", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,9 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.gree.internal.GreeCryptoUtil;
|
||||
import org.openhab.binding.gree.internal.GreeException;
|
||||
import org.openhab.binding.gree.internal.gson.GreeScanReponsePackDTO;
|
||||
import org.openhab.binding.gree.internal.gson.GreeScanRequestDTO;
|
||||
import org.openhab.binding.gree.internal.gson.GreeScanResponseDTO;
|
||||
import org.openhab.binding.gree.internal.gson.GreeScanResponsePackDTO;
|
||||
import org.openhab.binding.gree.internal.handler.GreeAirDevice;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
@ -103,12 +103,12 @@ public class GreeDeviceFinder {
|
||||
}
|
||||
|
||||
// Decrypt message - a GreeException is thrown when something went wrong
|
||||
String decryptedMsg = scanResponseGson.decryptedPack = GreeCryptoUtil
|
||||
.decryptPack(GreeCryptoUtil.getAESGeneralKeyByteArray(), scanResponseGson.pack);
|
||||
String decryptedMsg = scanResponseGson.decryptedPack = GreeCryptoUtil.decrypt(scanResponseGson);
|
||||
|
||||
logger.debug("Response received from address {}: {}", remoteAddress.getHostAddress(), decryptedMsg);
|
||||
|
||||
// Create the JSON to hold the response values
|
||||
scanResponseGson.packJson = GSON.fromJson(decryptedMsg, GreeScanReponsePackDTO.class);
|
||||
scanResponseGson.packJson = GSON.fromJson(decryptedMsg, GreeScanResponsePackDTO.class);
|
||||
|
||||
// Now make sure the device is reported as a Gree device
|
||||
if ("gree".equalsIgnoreCase(scanResponseGson.packJson.brand)) {
|
||||
|
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeBaseDTO class is used as a base class for request and response classes
|
||||
*
|
||||
* @author Zhivka Dimvoa - Initial contribution
|
||||
*/
|
||||
public class GreeBaseDTO {
|
||||
public String t = null;
|
||||
public int i = 0;
|
||||
public int uid = 0;
|
||||
public String cid = null;
|
||||
public String tcid = null;
|
||||
public String tag = null;
|
||||
public String pack = null;
|
||||
}
|
@ -14,7 +14,7 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeBindRequestPack4Gson class is used by Gson to hold values to be send to
|
||||
* The GreeBindRequestPackDTO class is used by Gson to hold values to be send to
|
||||
* the Air Conditioner during Binding
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
|
@ -14,20 +14,11 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeBindResponse4Gson class is used by Gson to hold values returned from
|
||||
* The GreeBindResponseDTO class is used by Gson to hold values returned from
|
||||
* the Air Conditioner during Binding
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
*/
|
||||
public class GreeBindResponseDTO {
|
||||
|
||||
public String t = null;
|
||||
public int i = 0;
|
||||
public int uid = 0;
|
||||
public String cid = null;
|
||||
public String tcid = null;
|
||||
public String pack = null;
|
||||
|
||||
public transient String decryptedPack = null;
|
||||
public class GreeBindResponseDTO extends GreeResponseBaseDTO {
|
||||
public transient GreeBindResponsePackDTO packJson = null;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeBindResponsePack4Gson class is used by Gson to hold values returned from
|
||||
* The GreeBindResponsePackDTO class is used by Gson to hold values returned from
|
||||
* the Air Conditioner during Binding
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
|
@ -14,21 +14,12 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeExecResponse4Gson class is used by Gson to hold values returned from
|
||||
* The GreeExecResponseDTO class is used by Gson to hold values returned from
|
||||
* the Air Conditioner during requests for Execution of Commands to the
|
||||
* Air Conditioner.
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
*/
|
||||
public class GreeExecResponseDTO {
|
||||
|
||||
public String t = null;
|
||||
public int i = 0;
|
||||
public int uid = 0;
|
||||
public String cid = null;
|
||||
public String tcid = null;
|
||||
public String pack = null;
|
||||
|
||||
public transient String decryptedPack = null;
|
||||
public class GreeExecResponseDTO extends GreeResponseBaseDTO {
|
||||
public transient GreeExecResponsePackDTO packJson = null;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeExecResponsePack4Gson class is used by Gson to hold values returned from
|
||||
* The GreeExecResponsePackDTO class is used by Gson to hold values returned from
|
||||
* the Air Conditioner during requests for Execution of Commands to the
|
||||
* Air Conditioner.
|
||||
*
|
||||
|
@ -14,7 +14,7 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeExecuteCommandPack4Gson class is used by Gson to hold values to be send to
|
||||
* The GreeExecuteCommandPackDTO class is used by Gson to hold values to be send to
|
||||
* the Air Conditioner during requests for Execution of Commands to the
|
||||
* Air Conditioner.
|
||||
*
|
||||
|
@ -14,17 +14,11 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeReqStatus4Gson class is used by Gson to hold values to be send to
|
||||
* The GreeReqStatusDTO class is used by Gson to hold values to be send to
|
||||
* the Air Conditioner during requests for Status Updates to the
|
||||
* Air Conditioner.
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
*/
|
||||
public class GreeReqStatusDTO {
|
||||
public String cid = null;
|
||||
public int i = 0;
|
||||
public String t = null;
|
||||
public int uid = 0;
|
||||
public String pack = null;
|
||||
public String tcid = null;
|
||||
public class GreeReqStatusDTO extends GreeRequestDTO {
|
||||
}
|
||||
|
@ -14,14 +14,13 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeReqStatusPack4Gson class is used by Gson to hold values to be send to
|
||||
* The GreeReqStatusPackDTO class is used by Gson to hold values to be send to
|
||||
* the Air Conditioner during requests for Status Updates to the
|
||||
* Air Conditioner.
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
*/
|
||||
public class GreeReqStatusPackDTO {
|
||||
|
||||
public String t = null;
|
||||
public String[] cols = null;
|
||||
public String mac = null;
|
||||
|
@ -14,17 +14,10 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeBindRequest4Gson class is used by Gson to hold values to be send to
|
||||
* the Air Conditioner during Binding
|
||||
* The GreeRequestDTO class is used by Gson to hold values to be send to
|
||||
* the Air Conditioner during Binding and as a base class for other request classes
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
*/
|
||||
public class GreeRequestDTO {
|
||||
|
||||
public int uid = 0;
|
||||
public String t = null;
|
||||
public int i = 0;
|
||||
public String pack = null;
|
||||
public String cid = null;
|
||||
public String tcid = null;
|
||||
public class GreeRequestDTO extends GreeBaseDTO {
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeResponseBaseDTO class is used as a base class for response classes
|
||||
*
|
||||
* @author Zhivka Dimvoa - Initial contribution
|
||||
*/
|
||||
public class GreeResponseBaseDTO extends GreeBaseDTO {
|
||||
public transient String decryptedPack = null;
|
||||
}
|
@ -14,7 +14,7 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeScanRequest4Gson class is used by Gson to hold values sent to
|
||||
* The GreeScanRequestDTO class is used by Gson to hold values sent to
|
||||
* the Air Conditioner during Scan Requests to the Air Conditioner.
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
|
@ -14,18 +14,11 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeScanResponse4Gson class is used by Gson to hold values returned by
|
||||
* The GreeScanResponseDTO class is used by Gson to hold values returned by
|
||||
* the Air Conditioner during Scan Requests to the Air Conditioner.
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
*/
|
||||
public class GreeScanResponseDTO {
|
||||
public String t = null;
|
||||
public int i = 0;
|
||||
public int uid = 0;
|
||||
public String cid = null;
|
||||
public String tcid = null;
|
||||
public String pack = null;
|
||||
public transient String decryptedPack = null;
|
||||
public transient GreeScanReponsePackDTO packJson = null;
|
||||
public class GreeScanResponseDTO extends GreeResponseBaseDTO {
|
||||
public transient GreeScanResponsePackDTO packJson = null;
|
||||
}
|
||||
|
@ -14,13 +14,12 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeScanReponsePack4Gson class is used by Gson to hold values returned by
|
||||
* The GreeScanReponsePackDTO class is used by Gson to hold values returned by
|
||||
* the Air Conditioner during Scan Requests to the Air Conditioner.
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
*/
|
||||
public class GreeScanReponsePackDTO {
|
||||
|
||||
public class GreeScanResponsePackDTO {
|
||||
public String t = null;
|
||||
public String cid = null;
|
||||
public String bc = null;
|
@ -14,21 +14,12 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeStatusResponse4Gson class is used by Gson to hold values returned from
|
||||
* The GreeStatusResponseDTO class is used by Gson to hold values returned from
|
||||
* the Air Conditioner during requests for Status Updates to the
|
||||
* Air Conditioner.
|
||||
*
|
||||
* @author John Cunha - Initial contribution
|
||||
*/
|
||||
public class GreeStatusResponseDTO {
|
||||
|
||||
public String t = null;
|
||||
public int i = 0;
|
||||
public int uid = 0;
|
||||
public String cid = null;
|
||||
public String tcid = null;
|
||||
public String pack = null;
|
||||
|
||||
public transient String decryptedPack = null;
|
||||
public class GreeStatusResponseDTO extends GreeResponseBaseDTO {
|
||||
public transient GreeStatusResponsePackDTO packJson = null;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ package org.openhab.binding.gree.internal.gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* The GreeStatusResponsePack4Gson class is used by Gson to hold values returned from
|
||||
* The GreeStatusResponsePackDTO class is used by Gson to hold values returned from
|
||||
* the Air Conditioner during requests for Status Updates to the
|
||||
* Air Conditioner.
|
||||
*
|
||||
|
@ -64,6 +64,7 @@ public class GreeAirDevice {
|
||||
private final InetAddress ipAddress;
|
||||
private int port = 0;
|
||||
private String encKey = "";
|
||||
private GreeCryptoUtil.EncryptionTypes encType = GreeCryptoUtil.EncryptionTypes.ECB;
|
||||
private Optional<GreeScanResponseDTO> scanResponseGson = Optional.empty();
|
||||
private Optional<GreeStatusResponseDTO> statusResponseGson = Optional.empty();
|
||||
private Optional<GreeStatusResponsePackDTO> prevStatusResponsePackGson = Optional.empty();
|
||||
@ -76,6 +77,7 @@ public class GreeAirDevice {
|
||||
this.ipAddress = ipAddress;
|
||||
this.port = port;
|
||||
this.scanResponseGson = Optional.of(scanResponse);
|
||||
this.encType = GreeCryptoUtil.getEncryptionType(scanResponse);
|
||||
}
|
||||
|
||||
public void getDeviceStatus(DatagramSocket clientSocket) throws GreeException {
|
||||
@ -117,9 +119,8 @@ public class GreeAirDevice {
|
||||
String reqStatusPackStr = GSON.toJson(reqStatusPackGson);
|
||||
|
||||
// Encrypt and send the Status Request pack
|
||||
String encryptedStatusReqPacket = GreeCryptoUtil.encryptPack(getKey(), reqStatusPackStr);
|
||||
DatagramPacket sendPacket = createPackRequest(0,
|
||||
new String(encryptedStatusReqPacket.getBytes(), StandardCharsets.UTF_8));
|
||||
String[] encryptedStatusReqData = GreeCryptoUtil.encrypt(getKey(), reqStatusPackStr, encType);
|
||||
DatagramPacket sendPacket = createPackRequest(0, encryptedStatusReqData);
|
||||
clientSocket.send(sendPacket);
|
||||
|
||||
// Keep a copy of the old response to be used to check if values have changed
|
||||
@ -131,7 +132,7 @@ public class GreeAirDevice {
|
||||
|
||||
// Read the response, create the JSON to hold the response values
|
||||
GreeStatusResponseDTO resp = receiveResponse(clientSocket, GreeStatusResponseDTO.class);
|
||||
resp.decryptedPack = GreeCryptoUtil.decryptPack(getKey(), resp.pack);
|
||||
resp.decryptedPack = GreeCryptoUtil.decrypt(getKey(), resp, encType);
|
||||
logger.debug("Response from device: {}", resp.decryptedPack);
|
||||
resp.packJson = GSON.fromJson(resp.decryptedPack, GreeStatusResponsePackDTO.class);
|
||||
|
||||
@ -157,14 +158,14 @@ public class GreeAirDevice {
|
||||
String bindReqPackStr = GSON.toJson(bindReqPackGson);
|
||||
|
||||
// Encrypt and send the Binding Request pack
|
||||
String encryptedBindReqPacket = GreeCryptoUtil.encryptPack(GreeCryptoUtil.getAESGeneralKeyByteArray(),
|
||||
bindReqPackStr);
|
||||
DatagramPacket sendPacket = createPackRequest(1, encryptedBindReqPacket);
|
||||
String[] encryptedBindReqData = GreeCryptoUtil.encrypt(GreeCryptoUtil.getGeneralKeyByteArray(encType),
|
||||
bindReqPackStr, encType);
|
||||
DatagramPacket sendPacket = createPackRequest(1, encryptedBindReqData);
|
||||
clientSocket.send(sendPacket);
|
||||
|
||||
// Recieve a response, create the JSON to hold the response values
|
||||
GreeBindResponseDTO resp = receiveResponse(clientSocket, GreeBindResponseDTO.class);
|
||||
resp.decryptedPack = GreeCryptoUtil.decryptPack(GreeCryptoUtil.getAESGeneralKeyByteArray(), resp.pack);
|
||||
resp.decryptedPack = GreeCryptoUtil.decrypt(resp, encType);
|
||||
resp.packJson = GSON.fromJson(resp.decryptedPack, GreeBindResponsePackDTO.class);
|
||||
|
||||
// Now set the key and flag to indicate the bind was successful
|
||||
@ -424,13 +425,13 @@ public class GreeAirDevice {
|
||||
String execCmdPackStr = GSON.toJson(execCmdPackGson);
|
||||
|
||||
// Now encrypt and send the Command Request pack
|
||||
String encryptedCommandReqPacket = GreeCryptoUtil.encryptPack(getKey(), execCmdPackStr);
|
||||
DatagramPacket sendPacket = createPackRequest(0, encryptedCommandReqPacket);
|
||||
String[] encryptedCommandReqData = GreeCryptoUtil.encrypt(getKey(), execCmdPackStr, encType);
|
||||
DatagramPacket sendPacket = createPackRequest(0, encryptedCommandReqData);
|
||||
clientSocket.send(sendPacket);
|
||||
|
||||
// Receive and decode result
|
||||
GreeExecResponseDTO execResponseGson = receiveResponse(clientSocket, GreeExecResponseDTO.class);
|
||||
execResponseGson.decryptedPack = GreeCryptoUtil.decryptPack(getKey(), execResponseGson.pack);
|
||||
execResponseGson.decryptedPack = GreeCryptoUtil.decrypt(getKey(), execResponseGson, encType);
|
||||
|
||||
// Create the JSON to hold the response values
|
||||
execResponseGson.packJson = GSON.fromJson(execResponseGson.decryptedPack, GreeExecResponsePackDTO.class);
|
||||
@ -451,14 +452,21 @@ public class GreeAirDevice {
|
||||
executeCommand(clientSocket, Map.of(command, value));
|
||||
}
|
||||
|
||||
private DatagramPacket createPackRequest(int i, String pack) {
|
||||
private DatagramPacket createPackRequest(int i, String[] data) {
|
||||
GreeRequestDTO request = new GreeRequestDTO();
|
||||
request.cid = GREE_CID;
|
||||
request.i = i;
|
||||
request.t = GREE_CMDT_PACK;
|
||||
request.uid = 0;
|
||||
request.tcid = getId();
|
||||
request.pack = pack;
|
||||
request.pack = data[0];
|
||||
if (encType == GreeCryptoUtil.EncryptionTypes.GCM) {
|
||||
if (data.length > 1) {
|
||||
request.tag = data[1];
|
||||
} else {
|
||||
logger.warn("Missing string for tag property for GCM encryption data");
|
||||
}
|
||||
}
|
||||
byte[] sendData = GSON.toJson(request).getBytes(StandardCharsets.UTF_8);
|
||||
return new DatagramPacket(sendData, sendData.length, ipAddress, port);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user