Skip to content

Instantly share code, notes, and snippets.

@lapo-luchini
Created July 1, 2023 14:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lapo-luchini/6a960c80db44d3137e0c2c0e6e71d292 to your computer and use it in GitHub Desktop.
Save lapo-luchini/6a960c80db44d3137e0c2c0e6e71d292 to your computer and use it in GitHub Desktop.
Decode encrypted KNX project using NodeJS
import util from 'node:util';
import * as fs from 'node:fs/promises';
import * as crypto from 'node:crypto';
import Minizip from 'minizip-asm.js';
const
reFile = /^P-[0-9A-F]{4}([/]0[.]xml|[.]zip)$/,
pbkdf2 = util.promisify(crypto.pbkdf2);
export async function decodeProject(proj, password) {
const zip = await fs.readFile(proj);
const mz = new Minizip(zip);
const file = mz.list().filter(f => reFile.test(f.filepath))[0];
const encrypted = file.filepath.endsWith('.zip');
let data = mz.extract(file.filepath);
if (encrypted) {
// from https://github.com/XKNX/xknxproject/blob/main/xknxproject/zip/extractor.py#L174
// which is covered by GNU GENERAL PUBLIC LICENSE Version 2, June 1991
const pwd2 = (await pbkdf2(Buffer.from(password, 'utf-16le'), '21.project.ets.knx.org', 65536, 32, 'sha256')).toString('base64');
const mz = new Minizip(data);
data = mz.extract('0.xml', {password: pwd2});
}
return data.toString('utf8');
}
console.log(await decodeProject(process.argv[2], process.argv[3]));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment