Download on hex.pm/packages/ex_windows_api_dataprotection.
Access the Windows Data Protection API (DPAPI) from Elixir.
The Microsoft Windows Data Protection API (DPAPI) features functions for encrypting/wrapping/protecting and decrypting/unwrapping/unprotecting data, namely CryptProtectData and CryptUnprotectData. These functions are defined in dpapi.h
.
The DPAPI on Windows is similar to other mechanisms, such as KeyChain on MacOS. The difference certainly is that DPAPI only takes care of encryption/decryption, and the user supplies the plaintext or ciphertext. Under the hood, Windows stores key material in the Windows registry, so that only the currently logged-in user, on the current machine, can decrypt the data encrypted by that user on that machine.
The following sample demonstrates it:
import Windows.API.DataProtection, only: [wrap: 1, unwrap: 1]
"Hello world"
|> wrap()
|> unwrap()
returns "Hello world"
.
I needed access to the Azure CLI's MSAL token cache, which is in my user directory (%USERPROFILE%\.azure\msal_token_cache.bin
).
On Linux and MacOS, this token cache is an un-encrypted JSON file (~/.azure/msal_token_cache.json
).
However, on Windows, it's protected / encrypted, using DPAPI. With this module, I can access the JSON contents by unwrapping, with such an Elixir script:
Mix.install([
{:ex_windows_api_dataprotection, "~> 0.1.2"}
])
[System.user_home!(), ".azure", "msal_token_cache.bin"]
|> Path.join
|> File.read!()
|> Windows.API.DataProtection.unwrap()
|> IO.puts()
Thanks to @brainlid, @dbern-stripe, and @cadebward for featuring this little library in the "Thinking Elixir podcast / Magic Links episode 184, starting at minute 4:04...