Skip to content

Instantly share code, notes, and snippets.

@Zegnat
Last active March 14, 2019 12:44
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 Zegnat/f75a6090b02936eaa186790816b7d6ba to your computer and use it in GitHub Desktop.
Save Zegnat/f75a6090b02936eaa186790816b7d6ba to your computer and use it in GitHub Desktop.
Simple script for accessing the contents of an encrypted andOTP backup.

andOTP Decrypt

Simple script for accessing the contents of an encrypted andOTP backup. As long as Sodium is available this does not require any dependencies outside of PHP.

This was written as a replacement for asmw/andOTP-decrypt, which I found a little annoying to get going and depends on several external packages. (Hold! Was PHP easier than Python here? Oh my!)

Usage

To decrypt and write to a JSON file:

./decrypt.php otp_accounts.json.aes > otp_accounts.json

The script will prompt you to enter the password used when making the backup.

As the decoded JSON is written to STDOUT, it can be piped into other applications or scripts as well, potentially keeping your secrets from being written to disk. E.g. using jq to only write out the labels in order of most recently used:

./decrypt.php otp_accounts.json.aes | jq 'sort_by(-.last_used) | [.[].label]'

A more advanced use-case of this would be to automatically generate the otpauth URLs for feeding into a different authenticator application. I started on this but didn’t complete the jq command neccessary. If you end up doing it, let me know! Here is a start:

./decrypt.php otp_accounts.json.aes | jq '.[] | "otpauth://" + (.type | ascii_downcase) + "/" + (.label | @uri) + "?secret=" + .secret + "&algorithm=" + .algorithm'

permission denied: ./decrypt.php

If your command line tells you permission denied, you can either try and run the commands via your PHP executable or try to make the script itself executable:

php decrypt.php otp_accounts.json.aes > otp_accounts.json
chmod +x decrypt.php
#!/usr/bin/env php
<?php
declare(strict_types = 1);
fputs(STDERR, "Password: ");
$sttyMode = shell_exec('stty -g');
shell_exec('stty -echo');
$value = trim(fgets(STDIN, 4096));
shell_exec(sprintf('stty %s', $sttyMode));
fputs(STDERR, "\n");
$key = hash('sha256', $value, true);
sodium_memzero($value);
$input = new SplFileObject($argv[1], 'r');
$nonce = $input->fread(12);
$ciphertext = $input->fread($input->getSize());
$input = null;
$out = sodium_crypto_aead_aes256gcm_decrypt($ciphertext, '', $nonce, $key);
sodium_memzero($key);
if (false === $out) {
fputs(STDERR, "Could not be decrypted.");
exit(1);
}
fputs(STDOUT, $out . "\n");
sodium_memzero($out);
exit();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment