Context: I replaced my passphrase prompted at launch by a keyfile, stored on a USB dongle. My question concerns the step: # cryptsetup luksAddKey /path/to/mykeyfile .

I generated my added key is made this way: dd if=/dev/urandom of=mykeyfile bs=512 count=4 .

**I aim to make it run in a bash (it works...), but without passphrase prompt, and finally with zero prompt. ** My question:

  • Can I do something like cryptsetup luksAddKey -passphrase "Hello, my name is Jolly Roger" /path/to/mykeyfile ?
  • Or at least, can I pass the passphrase to an argument to my script call ? # sh myscript.sh -passphrase "Jolly..."

It does exist for SSH, sshpass.

Security Note : I dont care at all writing the passphrase in a script, cause it is replaced in /etc/crypttab by the keyfile. In addition, the script is to be used by confidential inhouse members. It is private.


If the key does not contain any newlines, you could simply pipe it in.

# cryptsetup luksFormat foobar.img originalkey

This will overwrite data on foobar.img irrevocably.

Are you sure? (Type uppercase yes): YES

# cryptsetup luksAddKey foobar.img newkey < originalkey

Unfortunately cryptsetup has several modes of handling keyfiles, and treats newlines and such differently depending which mode it is in. For special character keys, piping does not work:

# cryptsetup luksAddKey foobar.img newkey < originalkey
No key available with this passphrase.

In this case you'd need the keyfile option:

# cryptsetup luksAddKey --key-file=originalkey foobar.img newkey

Or if you still want to pipe it,

# cryptsetup luksAddKey --key-file=- foobar.img newkey < originalkey

Confusing, eh? Ambiguity can be avoided if you use keys that are ASCII only, not longer than 512 characters, and do not contain any unprintable characters so you could also type it manually in a pinch.

If possible you should avoid things like --password=xyz. This information is public, it leaks your passwords to the process list, shell history, and possibly other places. Always use pipes or files with properly restricted read permissions.

  • @frostschitz Danke. Actually I my added key is made this way: dd if=/dev/urandom of=mykeyfile bs=512 count=4 . Anyway this remains a prompt: ` Are you sure? (Type uppercase yes): YES` and I aim zero prompt. – ArchiT3K Aug 24 '15 at 12:15
  • 1
    You'll have to use --key-file then. For keyfiles that can be used in a simple pipe (or even typed), use something like echo -n $(pwgen -sy 512 1) > keyfile. (pwgen also uses /dev/urandom; echo -n removes the newline at the end) – frostschutz Aug 24 '15 at 12:22
  • @Strukt, the prompt is only for luksFormat, not for luksAddKey. The luksFormat in my answer was only to show an example, obviously you should not luksFormat yours or lose all your data! You can get rid of the YES prompt using --batch-mode. – frostschutz Aug 24 '15 at 12:24
  • You documented well, very. But I finally does not understand. at all. – ArchiT3K Aug 24 '15 at 12:42
  • Using format instead ofadd seems to be my way. The prompt is a hassle cause I use Zenity – ArchiT3K Aug 24 '15 at 12:47

To answer your question, just pipe the passphrase in the stdin. So do a :

zenity --password | cryptsetup luksAddKey /dev/mydevice /path/to/my/keyfile

For more information, the --key-file allows you to point to a file being a key to unlock the device. And you could use --key-file=- to use information from stdin. But this needs to be a keyfile. Not a file containing your password.


cat /tmp/fileContainingPassword | cryptsetup luksAddKey /dev/mydevice /path/to/my/new/keyfile


cat /path/to/keyfile | cryptsetup luksAddKey --key-file=- /dev/mydevice /path/to/my/new/keyfile

are different. The first reads a password to unlock the device from stdin.
The second reads a keyfile to unlock the device from stdin.

Keyfiles and passwords are treated differently by cryptsetup.

Another information: the --key-file option is only to read an already assigned keyfile to the device to unlock the device as to add a new key. To assign a new key, you can only point to a file. There are no - options to read from the stdin. If you don't want leave anything on the file system but still not type anything on the prompt (neither the unlocking passphrase, neither the new passphrase), then you'll have to use named pipes.

mkfifo /tmp/mytmpkey
# Here we put the process in the background with &,
# otherwise, it would block until
# cryptsetup read the value from /tmp/mytmpkey
dd if=/dev/urandom of=/tmp/mytmpkey bs=512 count=4 & 
cryptsetup luksAddKey --key-file /path/to/unlockKey /tmp/mytmpkey
rm /tmp/mytmpkey 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.