]> git.basschouten.com Git - openhab-addons.git/blob
645b39b187bd9a0d448c578884811a798f4c3159
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.tplinksmarthome.internal;
14
15 import java.io.ByteArrayInputStream;
16 import java.io.DataInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.nio.ByteBuffer;
20 import java.nio.charset.StandardCharsets;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23
24 /**
25  * Util class to encypt and decrypt data to be sent to and from the smart plug.
26  *
27  * @author Hilbrand Bouwkamp - Initial contribution
28  */
29 @NonNullByDefault
30 public final class CryptUtil {
31
32     private static final int KEY = 171;
33
34     private CryptUtil() {
35         // Util class
36     }
37
38     /**
39      * Decrypt the byte array of the specified length. The length is necessary because the byte array might be larger
40      * than the actual content.
41      *
42      * @param data byte array containing the data
43      * @param length number of bytes in the byte array to read
44      * @return decrypted String of the byte array
45      * @throws IOException exception in case device not reachable
46      */
47     public static String decrypt(byte[] data, int length) throws IOException {
48         try (ByteArrayInputStream is = new ByteArrayInputStream(data)) {
49             return decrypt(is, length);
50         }
51     }
52
53     /**
54      * Decrypt the byte data in the input stream. In the first 4 bytes the length of the data in the byte array is
55      * coded.
56      *
57      * @param inputStream input stream containing length and data
58      * @return decrypted String of the inputstream
59      * @throws IOException exception in case device not reachable
60      */
61     public static String decryptWithLength(InputStream inputStream) throws IOException {
62         try (DataInputStream is = new DataInputStream(inputStream)) {
63             return decrypt(is, is.readInt());
64         }
65     }
66
67     /**
68      * Decrypt the byte data in the input stream with the length as given.
69      *
70      * @param inputStream input stream
71      * @param length the number of bytes to read
72      * @return decrypted String of the inputstream
73      * @throws IOException exception in case device not reachable
74      */
75     private static String decrypt(InputStream inputStream, int length) throws IOException {
76         final byte[] decryptedData = new byte[length];
77         int in;
78         int key = KEY;
79         int i = 0;
80         while (i < length && (in = inputStream.read()) != -1) {
81             final int nextKey = in;
82             decryptedData[i++] = (byte) (in ^ key);
83             key = nextKey;
84         }
85         return new String(decryptedData, StandardCharsets.UTF_8);
86     }
87
88     /**
89      * Encrypts the string into a byte array with the first for bytes specifying the length of the given String. The
90      * length is not encrypted.
91      *
92      * @param string String to encrypt
93      * @return byte array with length and encrypted string
94      */
95     public static byte[] encryptWithLength(String string) {
96         ByteBuffer bb = ByteBuffer.allocate(4 + string.length());
97         bb.putInt(string.length());
98         bb.put(encrypt(string));
99         return bb.array();
100     }
101
102     /**
103      * Encrypts the string into a byte array.
104      *
105      * @param string String to encrypt
106      * @return byte array with encrypted string
107      */
108     public static byte[] encrypt(String string) {
109         byte[] buffer = new byte[string.length()];
110         byte key = (byte) KEY;
111         for (int i = 0; i < string.length(); i++) {
112             buffer[i] = (byte) (string.charAt(i) ^ key);
113             key = buffer[i];
114         }
115         return buffer;
116     }
117 }