Open sburke781 opened 3 years ago
Following communications issues for @bikesquid in recent days, I have taken another look at Fraser Sim's Typescript example for Homebridge and have made some note's on the encode token method:
// calcuate a token - based on pykumo and homebridge-kumo-local
const W = this.h2l(KUMO_KEY);
const p = base64.decode(password);
const data_hash = sjcl.codec.hex.fromBits(
sjcl.hash.sha256.hash(
sjcl.codec.hex.toBits(
this.l2h(
Array.prototype.map.call(p + post_data, (m2) => {
return m2.charCodeAt(0);
}),
),
),
),
);
// convert data_hash to byteArray
const data_hash_byteArray = this.h2l(data_hash);
// Part # 1 - Decode the password
const p = base64.decode(password);
Returns a byte[] or string(?) of decoded password string from Kumo
// Encode def encoded = text.bytes.encodeBase64().toString() println encoded
// Decode byte[] decoded = encoded.decodeBase64() println new String(decoded)
// Part # 2
SHA256 Hash
Could originalString below just be = password.decodeBase64() + post_data
MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] encodedhash = digest.digest( originalString.getBytes(StandardCharsets.UTF_8));
producing data_hash_byteArray from Typescript example
// Part # 3
Mashing together data_hash_byteArray, Kumo Key and CryptoSerial
const intermediate = new Uint8Array(88); for (let i = 0; i < 32; i++) { intermediate[i] = W[i]; intermediate[i + 32] = data_hash_byteArray[i]; } intermediate[64] = 8; intermediate[65] = 64; intermediate[66] = 0; //S_PARAM
// convert cryptoSerial to byte array
const cryptoserial = this.h2l(cryptoSerial);
intermediate[79] = cryptoserial[8];
for (let i = 0; i < 4; i++) {
intermediate[i + 80] = cryptoserial[i + 4];
intermediate[i + 84] = cryptoserial[i];
}
This should all translate easily as quivalent array manipulation in Groovy
// Part # 4
Do SHA-256 hash of intermediate Byte array
const hash = sjcl.codec.hex.fromBits( sjcl.hash.sha256.hash(sjcl.codec.hex.toBits(this.l2h(intermediate))), ); return hash;
Use Message Digest again.... Without needing to convert a string to a byte array
MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] encodedhash = digest.digest( originalString.getBytes(StandardCharsets.UTF_8));
Convert encodedHash[] to Hex String
private static String bytesToHex(byte[] hash) { StringBuilder hexString = new StringBuilder(2 * hash.length); for (int i = 0; i < hash.length; i++) { String hex = Integer.toHexString(0xff & hash[i]); if(hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); }
Expand the Unified Thermostat Drivers to include local control of air conditioning units, removing the reliance on the cloud services.