agentsclimarketplace

Aes256gcm machineid credential store

Skill kjuhwa/skills-hub/skills/security/aes256gcm-machineid-credential-store

Self-correcting knowledge corpus for Claude Code — 9 stable shape clusters, bias-correction pipeline baked into contribution flow. 47 papers, 45 techniques, 1.1k skills.

Install
npx -y skills add kjuhwa/skills-hub --skill aes256gcm-machineid-credential-store

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Cross-platform encrypted credential file (AES-256-GCM) keyed with a PBKDF2-derived key whose salt is pulled from a hardware-stable OS identifier so the store survives hostname/DHCP changes.

SKILL.md

3.1 KB, as published. Nobody here has run it

AES-256-GCM credential store keyed on machine ID

When to use

  • Desktop/CLI app storing API keys, OAuth refresh tokens, etc. without a backing keychain prompt.
  • Want cross-platform (macOS / Windows / Linux) without native keytar bindings.
  • Need data authenticity (tamper detection), not just confidentiality - GCM gives both.

How it works

  1. Stable hardware ID per OS:
    • macOS: ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID -> parse the quoted UUID. Tied to the logic board.
    • Windows: reg query HKLM\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid -> parse MachineGuid REG_SZ …. Set at OS install.
    • Linux: /var/lib/dbus/machine-id (fallback /etc/machine-id). Set at OS install.
    • Fallback: username + homedir string.
  2. Key derivation: pbkdf2Sync(machineId, salt, 100_000, 32, 'sha256'). Salt is stored in the file header.
  3. File layout (CRAFT01\0 magic + 4B flags + 32B salt + 20B reserved = 64B header, then IV(12) | authTag(16) | ciphertext).
  4. Encrypt: createCipheriv('aes-256-gcm', key, iv); update + final; getAuthTag().
  5. Decrypt: same, decipher.setAuthTag(tag) before final() - throws if tampered.
  6. Legacy migration: if magic bytes don't match, try the old hostname-based key first, re-encrypt with new key, write back.

Example

import { createCipheriv, randomBytes, pbkdf2Sync } from 'crypto';
const MACHINE_ID = getStableMachineId(); // see OS-specific calls above
const salt = randomBytes(32);
const key = pbkdf2Sync(MACHINE_ID, salt, 100_000, 32, 'sha256');
const iv = randomBytes(12);
const cipher = createCipheriv('aes-256-gcm', key, iv);
const enc = Buffer.concat([cipher.update(JSON.stringify(data), 'utf8'), cipher.final()]);
const tag = cipher.getAuthTag();
writeFileSync(path, Buffer.concat([MAGIC, flags, salt, reserved, iv, tag, enc]));

Gotchas

  • The derived key never leaves process memory, but anyone with ROOT/admin on the box can still call ioreg/reg and decrypt. This is about offline exfiltration protection, not local root.
  • DON'T use hostname() as the machine ID - it changes with Wi-Fi, VPNs, DHCP. Learned the hard way; migration code needed.
  • PBKDF2 100k iterations is on the low end by 2026 standards; consider Argon2 for new designs. Trade-off: app startup latency.
  • Remember to setAuthTag BEFORE final() on decryption. Forgetting = OperationError.
  • Keep a 64-byte fixed header with a magic string + flags field reserved for future format changes.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.