Encrypting file using GnuPG on command line hangs forever - encryption

There is one file I want to encrypt with GnuPG by
gpg2 --homedir=~/.gnupg --always-trust=true --recipient="BlahBlah" --encrypt=/path/to/file --output=/path/to/output_file
However this command seems to hang forever and never return. Interestingly, after I interrupt process, there is indeed /path/to/output_file created , however the bytes written there is much bigger than raw payload (for example my /path/to/file is only of 5 bytes but it turns out there are nearly 200 bytes written to /path/to/output_file).
There must be something wrong, but I really couldn't figure out what is it.
I have in advance imported the key for BlahBlah by gpg --import key.asc. It happens both for GnuPG 1 and GnuPG 2.

You're applying --encrypt in a wrong way. --encrypt does not expect any parameters, the file(s) to be worked on are passed as very last arguments. Additionally, following the documentation you should pass --output /path/to/output_file instead of --output=/path/to/output_file. Finally, GnuPG distinguishes between options and commands, and options should precede commands.
What you observe is that GnuPG starts writing header information, but then waits for input from STDIN (until interrupted).
The GnuPG command line you're looking for is
gpg2 --homedir=~/.gnupg --always-trust=true --recipient="BlahBlah" --output /path/to/output_file --encrypt /path/to/file
One last hint: the combination of --always-trust=true and resolving a recipient by user ID is a very bad idea, as any other key with the same user ID in the local keyring might be used. Pass the full key's fingerprint instead, which specifically selects a distinct key (using short key IDs is not secure, either).

Related

FFmpeg concat demuxer and handling encrypted chunks

I'm trying to process a remote m3u8 playlist containing (a possibly encrypted) HLS stream. The output I'm looking for is a mp4 container with MPEG-4 inside.
The playlist is a result of an ended live stream and may contain EXT-X-DISCONTINUITY tags. As I understand, there's no "built-in" way to process it and indeed, there are plenty of warnings like "Non-monotonous DTS in output stream" and the resulting file always has some playback issues.
There are a couple of options to "glue" it. On an unencrypted stream, I found concat demuxer to produce the result with the least playback problems. The command is:
LIST=chunks.list; ffmpeg -loglevel 'debug' -f concat -safe 0 -protocol_whitelist "file,http,https,tcp,tls,crypto" -i $LIST -c copy -movflags frag_keyframe -y output_concat.mp4
where chunks.list is something like:
file 'https://www.example.org/chunk1.ts'
file 'https://www.example.org/chunk2.ts'
file 'https://www.example.org/chunk3.ts'
Now, I'm trying to use concat demuxer to process encrypted chunks. I've tried passing -key and -iv options in different places and changing chunks.list to be like file 'crypto+https...' but it won't pick up encryption key:
Opening an input file: chunks.list.
[concat # 0x7f9fb6800c00] Opening 'chunks.list' for reading
[NULL # 0x7f9fb6007e00] Opening 'crypto+https://www.example.org/chunk1.ts' for reading
[crypto # 0x7f9fb5700a00] decryption key not set
[concat # 0x7f9fb6800c00] Impossible to open 'crypto+https://www.example.org/chunk1.ts'
[AVIOContext # 0x7f9fb5700780] Statistics: 5094 bytes read, 0 seeks
chunks.list: Invalid argument
Docs mention encryption options for crypto protocol, so it looks it's just a matter of passing these in a proper way.
When, instead of using concat demuxer, I try to process and decrypt only one chunk like:
ffmpeg -i crypto+https://www.example.org/chunk1.ts -key <my_hex_key> -iv <my_iv> chunk1.ts it works fine. There's nothing wrong with the key itself, I'm able to decrypt it with other tools (openssl etc).
Is it possible for concat demuxer to handle decryption? If so, where should I pass key and iv options?

GPG - Change passphrase non interactively

Most other GPG commands allow you to use --batch mode, but it doesn't appear to be the case when trying to edit a passphrase.
You have to run gpg --edit-key user
Which opens up an interactive GPG prompt.
This isn't going to work in my case as I need the ability to change the passphrase without the command line interaction.
The closest thing I've found is
gpg --batch --passphrase-fd 0 --status-fd 2 --command-fd 0 --edit-key
But this just gives me an invalid command after I enter the existing passphrase.
Any suggestions greatly appreciated.
I just encountered this problem while writing a key-gen script and came up with a solution!
A few things to note:
Lots of folks point towards --batch because --passphrase* requires it. In this case we'll be working with STDIN (as specified by --command-fd 0) and thus want to pass raw input rather than messing with the GnuPG functions.
While --status-fd 2 is useful for debugging, it isn't necessary. That said, including it lead me to the insight that --change-passphrase is requesting two, and only two, entries.
Set --pinentry-mode loopback to avoid having a prompt asking for your passphrase.
The solution is to pipe (or redirect) both the original and new passphrases to STDIN where GnuPG can processes them. While my initial code used (echo ..;echo ..)|gpg .. it is better to use a here-document.
# Using GnuPG to change PGP key passphrase non-interactively
gpg --command-fd 0 --pinentry-mode loopback \
--change-passphrase ${KEYID} <<END
${OLD_PASS}
${NEW_PASS}
END
Just set up the variables and that should work. Enjoy!

GPG: How to sign with multiple signatures with different passphrases?

I have a job that runs periodically and signs/encrypts a file like so:
$ gpg --homedir /path/to/.gnupg -r key1#mydomain.com -r key2#mydomain.com --local-user sig1#mydomain.com --batch --passphrase-file /path/to/gpg-password --sign -ea myfile
The command encrypts the file for two recipients: key1#mydomain.com and key2#mydomain.com. It signs the file with sig1#mydomain.com. It runs in batch mode as there is no human interactivity - this is an automated process. It gets the passphrase for the signature from /path/to/gpg-password.
What I would like to do is now sign the file with two signatures at the same time. Like so:
$ gpg --homedir /path/to/.gnupg -r key1#mydomain.com -r key2#mydomain.com --local-user sig1#mydomain.com --local-user sig2#mydomain.com --batch --passphrase-file /path/to/gpg-password --sign -ea myfile
gpg: skipped "sig2#mydomain.com": bad passphrase
It works fine in interactive mode (eg. without --batch), I just have to supply the two passphrases via the command line. However, in batch mode it fails as it tries to get the signatures from the file. The signature is only valid for one of the signing keys.
From the man page:
--passphrase-file file
Read the passphrase from file file. Only the first line will be read from file file. This can only be used if only one passphrase is supplied.
How do I tell it what the password is for each key?
You have different options.
Completely remove the passwords, since they're stored somewhere anyway.
Use the same password (as you already discovered).
Use the gpg-agent and preset the passphrase. I'm unsure whether this is GnuPG 2-only (usually installed as gpg2, maybe to be installed from a gnupg2 package). Presetting the passphrase is as easy as running gpg-preset-passphrase --preset [fingerprint]. You will have to run this command for each of the keys individually, and make sure to cache the passphrase for a given time (at least the processing time of adding all the passphrases, and then signing the file you want to sign).
For the sake of completeness, but impractical: sign the file individually for each key, then take apart the OpenPGP packets and recombine them adding all the signatures one after the other. Signing with multiple keys just creates multiple signature packets.
For anyone else in the same situation as me, I ended up working around this apparent deficiency of gpg by editing one of the signing keys to have the same password as the other (the password stored in the gpg-password file). This doesn't compromise security in this instance since the password is stored in a text file anyway - the real security is the password of the user that this commands runs from and the fact that the secret keys are kept secret). You can change the password on a key by doing gpg --edit-key <key_id>, then passwd. Don't forget to save after.

ecryptfs - relation of user entered passphrase to the FEKEK when mounting manually

I've been trying to set up encrypted folder following the instructions in https://wiki.archlinux.org/index.php/ECryptfs#Without_ecryptfs-utils. In that case a mount passphrase is manually created and wrapped using a chosen password ("Arch" in that example). This is working as expected.
There is yet another possibility how to manually set up things. Namely using simple mount e.g.:
mount -t ecryptfs ~/.Private/ ~/Private -o key=passphrase,ecryptfs_cipher=aes,ecryptfs_key_bytes=32,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=y
In this case I'm prompted for a [password] and after that folder is mounted.
My question is: where is the mount passphrase hidden in the second example? And how is my entered [password] related to it and to the FEKEK in this case.
Could anybody please explain?
Thank you in advance.
I think the entered passphrase becomes the "file encryption key, encryption key, or FEKEK" itself, and is temporarily stored in the kernel keyring (root's keyring if you need to mount with sudo) while the folder is mounted. You can see the keyring before & after mounting & unmounting with sudo keyctl show.
It does not store the passphrase/FEKEK anywhere on disk, unlike the method "Without ecryptfs-utils" in the ArchWiki you liked to, and the one in the ecryptfs-utils below.
FYI, using the ecryptfs-utils tools it will create a random (16 byte) passphrase to use, if you haven't specified your own passphrase, and it apparently is the file encryption key (FEKEK) / FNEK.
Looking in a couple of the ecryptfs-utils tools, (several are shell scripts) inside ecryptfs-migrate-home it collects some data and calls ecryptfs-setup-private, which has this function to generate a more secure 16 byte random passphrase/FEKEK/FNEK (that then gets "wrapped"/encrypted with your login passphrase and stored on disk):
random_passphrase () {
bytes=$1
# Pull $1 of random data from /dev/urandom,
# and convert to a string of hex digits
od -x -N $bytes --width=$bytes /dev/urandom | head -n 1 | sed "s/^0000000//" | sed "s/\s*//g"
}

how to add commands in .ssh/authorized_keys

I read on man sshd one can add post-login processing when a user logs in using a particular key:
environment="FOO=BAR" ssh-rsa AAA... keytag
But when I try to ssh into the system, the target host does not register the line and instead asks for a password. What is the right way of adding this? I would like to do something like
command="echo|mail -s ${USER},${HOSTNAME} a.monitored.email#example.com" ssh-rsa AAA... keytag
I am using Suse SLE 11 SP2.
Thanks
Dinesh
First, according to the documentation command = "command":
That specifies the command is executed Whenever This key is used for authentication. The command supplied by the user (if any) is ignored. The command is run on a pty if the client requests a pty; Otherwise it is run without a tty. If an 8-bit clean channel is required, one must not request a pty or specify no-pty Should. A quote May be included in the command by quoting it with a backslash. This option might be useful to restrict Un certain public keys to perform just a specific operation. An example might be a key That Permits remote backups but nothing else. Note That May specify the client TCP and / or X11 forwarding Explicitly UNLESS they 'are prohibited. The command originally supplied by the client is available in the SSH_ORIGINAL_COMMAND environment variable. Note That This option Applies to shell, command or subsystem execution. Also note This command That May be superseded by Either a sshd_config (5) ForceCommand directive or a command embedded in a certificate.
Using this option, it is possible to enforce execution of a given command when this key is used for authentication and no other.This is not what you're looking for.
To run a command after login you can add in the file ~/bashrc something like this:
if [[ -n $SSH_CONNECTION ]] ; then
echo|mail -s ${USER},${HOSTNAME} a.monitored.email#example.com"
fi
Second, you need to verify the permissions of the authorized_keys file and the folder / parent folders in which it is located.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
For more information see: https://www.complang.tuwien.ac.at/doc/openssh-server/faq.html#3.14

Resources