Skip to content

Instantly share code, notes, and snippets.

@herrdommel
Created June 13, 2024 08:12
Show Gist options
  • Save herrdommel/0537362176073fa0daab0f5bd213848f to your computer and use it in GitHub Desktop.
Save herrdommel/0537362176073fa0daab0f5bd213848f to your computer and use it in GitHub Desktop.
Ansible vault decryption in NodeJS
const crypto = require('crypto');
const password = "password";
const vault = `$ANSIBLE_VAULT;1.1;AES256
33343835306666636239373663396363643766613363343837646633343933376633323964663030
3134616235646661306436643134383333633730376233650a663466323032343633383061336461
36393261363338616337613039363435313631343437323164386661326633313339396238396236
3462393338636632650a653036663266373533343232393838343161396564333963643632653932
30386135636131656130346537356637396139323134386162306431376564346537633566666532
6331323061373237336639356165393563613765663864366231`;
const splitInput = (vault) => {
const vaultNoHeader = vault.split("\n").slice(1).join("");
const [salt, hmac, payload] = vaultNoHeader.split("0a").map(e => Buffer.from(e, "hex"));
return [salt.toString(), hmac.toString(), payload.toString()];
}
const deriveKey = (password, salt, iterations = 10000, keyLen = 80, algo = "sha256") => {
const saltBuffer = Buffer.from(salt.toString(), "hex")
const derivedKey = crypto.pbkdf2Sync(password, saltBuffer, iterations, keyLen, algo);
return derivedKey.toString("hex");
}
const checkHmac = (key, verify, algo = "sha256") => {
const hmac = crypto.createHmac(algo, Buffer.from(key, "hex"));
hmac.update(Buffer.from(payload, "hex"));
const digest = hmac.digest().toString("hex")
if (digest !== verify) {
throw new Error("HMac invalid");
}
}
const convert = (key, nonce, algo = 'aes-256-ctr') => {
const decipher = crypto.createDecipheriv(algo, Buffer.from(key, "hex"), Buffer.from(nonce, "hex"));
let decrypted = decipher.update(Buffer.from(payload, "hex"));
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString("utf-8");
}
const [salt, hmac, payload] = splitInput(vault);
const derivedKey = deriveKey(password, salt);
const hmacKey = derivedKey.slice(64, 128);
const aesKey = derivedKey.slice(0, 64);
const nonce = derivedKey.slice(128);
checkHmac(hmacKey, hmac);
console.log(convert(aesKey, nonce));
@herrdommel
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment