# How to create an Encrypted USB Stick in Linux


This post explains 2 things:
1. how you can encrypt an external usb drive using linux,
2. and how you can use that encrypted drive on a daily basis as a backup device.

## 1. How to encrypt a USB drive in Linux

This involves:
- erasing the drive thoroughly,
- creating a partition in the drive,
- encrypting the partition,
- creating a filesystem in the encrypted container,
- learning how to safely lock and eject the drive,
- optionally, learning how to add new or remove existing passphrase.


These steps above are one-time setup.
You purchase a drive and you do these steps once,
and then you're ready to start using it.

Let's begin.


### Erase the drive with `dd`

This ensures the whole drive is written with 'zero' bytes, making it hard for any recovery programs to access any data that was previously written to the drive.

The command to do this is `dd`.

But you need the device's name to use `dd`.
Get it with `lsblk`.

Run `lsblk` __before__ plugging the usb and keep the output in the screen.
Now plug the usb drive and run `lsblk` again. Whatever extra line shows up
is the one representing the usb drive.

The output might look like this:

```sh
$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
sda           8:0    1     0B  0 disk
sdb           8:16   1  57.3G  0 disk
zram0       252:0    0   3.8G  0 disk  [SWAP]
nvme0n1     259:0    0 238.5G  0 disk
├─nvme0n1p1 259:1    0     1G  0 part  /boot
└─nvme0n1p2 259:2    0 237.5G  0 part
  └─root    253:0    0 237.5G  0 crypt /var/log
                                       /var/cache/pacman/pkg
                                       /home
                                       /
```

`sdb` represents the usb drive that we just stuck in.

`lsblk` lists all devices attached to the system.
`nvme*` is the laptop's internal ssd and `zram` is its RAM.

Now you can use `sdb` as target output file to `dd` to erase its content.

`dd` is just a file-content copying command. Just like `cat`, except it is
low-level.

Here, we're (over)writing every available bit of the drive with zero bytes with
the special `/dev/zero`, called as the "zero device" that just streams endless zero bytes when read from it.

So here's the command to erase your drive:

```
sudo dd if=/dev/zero of=/dev/sdb bs=4M status=progress
```

Note: This step might take hours. Make sure you plug in your laptop.

The output might be like this:

```sh
$ dd if=/dev/zero of=/dev/sdb bs=10M status=progress
33418117120 bytes (33 GB, 31 GiB) copied, 1900 s, 17.6 MB/s
61530439680 bytes (62 GB, 57 GiB) copied, 3569 s, 17.2 MB/s
dd: error writing '/dev/sdb': No space left on device
5869+0 records in
5868+0 records out
61530439680 bytes (62 GB, 57 GiB) copied, 3576.5 s, 17.2 MB/s
```


### Create a partition with `fdisk`

To use a usb drive to store data, it must first have at least one partition.

Run `sudo fdisk /dev/sdb` to create that.
This starts an interactive session where you can type:
- `d` to delete any existing partitions,
- `n` to create a new partition,
- and then finally `w` to persist the changes.

After partitioning, note the difference in `lsblk` output.
`sdb`'s partition `sdb1` is listed as a subtree (and the TYPE is `part`).

```sh
$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
sda           8:0    1     0B  0 disk
sdb           8:16   1  57.3G  0 disk
└─sdb1        8:17   1  57.3G  0 part
zram0       252:0    0   3.8G  0 disk  [SWAP]
nvme0n1     259:0    0 238.5G  0 disk
├─nvme0n1p1 259:1    0     1G  0 part  /boot
└─nvme0n1p2 259:2    0 237.5G  0 part
  └─root    253:0    0 237.5G  0 crypt /var/log
                                       /var/cache/pacman/pkg
                                       /home
                                       /
```


### Encrypt the partition with `cryptsetup`

Run this on the partition `sdb1` (not `sdb`. careful there):

```sh
sudo cryptsetup luksFormat /dev/sdb1
```

It'll warn about something dangerous.
Confirm it with 'YES' and
give a passphrase [that's easy for you to remember and hard for computers to guess](https://xkcd.com/936/).


### Create a filesystem with `mkfs.btrfs`

To create it, you must first open the encrypted partition with `cryptsetup open` like so:

```sh
sudo cryptsetup open /dev/sdb1 my_usb_stick
```

It'll ask for the passphrase. Type it and press enter and check `lsblk` again:

```sh
$ lsblk
NAME             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
sda                8:0    1     0B  0 disk
sdb                8:16   1  57.3G  0 disk
└─sdb1             8:17   1  57.3G  0 part
  └─my_usb_stick 253:1    0  57.3G  0 crypt
zram0            252:0    0   3.8G  0 disk  [SWAP]
nvme0n1          259:0    0 238.5G  0 disk
├─nvme0n1p1      259:1    0     1G  0 part  /boot
└─nvme0n1p2      259:2    0 237.5G  0 part
  └─root         253:0    0 237.5G  0 crypt /var/log
                                            /var/cache/pacman/pkg
                                            /home
                                            /
```

With the previous command `cryptsetup luksFormat`, you encrypted and __locked__ the drive.

This command `cryptsetup open` __unlocks__ the drive and allows you to access the partition. _(Only then you can create the filesystem.)_

It does so by creating a mapper.
Don't ask me to explain further. I don't know.
All I know is that opening allows the physical device to be mapped to the virtual device managed by the linux kernel.
Imagine that the device has now come from the physical realm onto the virtual realm.

The so called 'mapper' can be seen here:

```sh
$ ll /dev/mapper/my_usb_stick
Permissions Size User Date Modified Name
lrwxrwxrwx     - root 17 Oct 09:45  /dev/mapper/my_usb_stick -> ../dm-1
```

But it is of no use until it is mounted.
We'll see about that later.

Now, create a filesystem with `mkfs.btrfs`:

```sh
$ sudo mkfs.btrfs /dev/mapper/my_usb_stick
btrfs-progs v6.17
See https://btrfs.readthedocs.io for more information.

Label:              (null)
UUID:               02d146df-1234-44f3-b4556-eerrttew
Node size:          16384
Sector size:        4096        (CPU page size: 4096)
Filesystem size:    57.29GiB
Block group profiles:
  Data:             single            8.00MiB
  Metadata:         DUP               1.00GiB
  System:           DUP               8.00MiB
SSD detected:       no
Zoned device:       no
Features:           extref, skinny-metadata, no-holes, free-space-tree
Checksum:           dcr3r2e
Number of devices:  1
Devices:
   ID        SIZE  PATH
    1    57.29GiB  /dev/mapper/my_usb_stick

```

That's it, you now have created an encrypted usb drive that's ready to keep your secrets until its death!

But we're not done yet.


### Lock and 'Eject USB safely' with `cryptsetup close`
You unlocked the drive with `cryptsetup open`. Now lock it back with `cryptsetup close`:

```sh
sudo cryptsetup close my_usb_stick
```

Check `lsblk` now. The `my_usb_stick` "crypt type" line would be gone.

Now you can safely remove the usb.

What you now hold in your hand is the blood and brains of thousands of open-source geniuses that all worked to give you the ability to safely store your porn collection from the prying hands of your father.

Rejoice.

### [Bonus] Change password with `cryptsetup luksChangeKey`
__Note:__ This isn't your typical "Forgot your password?" kind of reset.
With LUKS encryption, if you forget the password, then you can forget your data as well.

The only reason to do this is because you think the password is compromised, or as a
standard security practice where you change the password every now and then.

So, you can do this with a single command:

```sh
sudo cryptsetup luksChangeKey /dev/sdb1
```

You can find the device name suffix `sdb1` with `lsblk`.

`luksChangeKey` will first ask you to type the existing password (passphrase, it calls it), and then the new one.

Give something that's strong and secure, but also easy to remember!

---


## 2. How to use an encrypted USB drive in Linux

This involves:
- unlocking the encrypted drive,
- mounting it,
- accessing the files in the drive (and transferring files to/from it),
- unmounting the drive,
- and locking it

Every time you plug in your encrypted usb drive to either backup your data to it, or to restore something from it, you're going to be doing these series of steps.

Let's begin.


### Unlock the drive with `cryptsetup open`

Just run this:

```sh
sudo cryptsetup open /dev/sdb1 my_usb_stick
```

And check `lsblk`. You'll see the unlocked partition. `my_usb_stick` is just a name. Can be anything.

__Warning Note:__ When you run the above `cryptsetup open` in a new terminal session, you'll instinctively start typing your passphrase.
But read the prompt carefully. It might be asking for your user's system password for sudo access!
Only after this the prompt asking for the passphrase will appear.

This command creates a 'mapper' at `/dev/mapper/my_usb_stick` which is what you'll mount
to the linux filesystem in the next command.


### Mount the drive with `mount`

Like so:

```sh
sudo mount /dev/mapper/my_usb_stick /mnt/my_usb_stick

```

The directory at `/mnt/my_usb_stick` should already exist.
If not, create it with `sudo mkdir /mnt/my_usb_stick`.
And ensure your system user has access to this directory. Otherwise `rsync` will fail. Do it with:

```sh
sudo chown -R $USER:$USER /mnt/my_usb_stick
```

Now check `lsblk`. You'll see that the unencrypted partition container is mounted at the said location:

```sh
$ lsblk
NAME             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
sda                8:0    1     0B  0 disk
sdb                8:16   1  57.3G  0 disk
└─sdb1             8:17   1  57.3G  0 part
  └─my_usb_stick 253:1    0  57.3G  0 crypt /mnt/my_usb_stick
zram0            252:0    0   3.8G  0 disk  [SWAP]
nvme0n1          259:0    0 238.5G  0 disk
├─nvme0n1p1      259:1    0     1G  0 part  /boot
└─nvme0n1p2      259:2    0 237.5G  0 part
  └─root         253:0    0 237.5G  0 crypt /var/log
                                            /var/cache/pacman/pkg
                                            /home
                                            /
```


### Use the drive (with `rsync` maybe)

Do whatever you want now. The files in the drive are now accessible:

```sh
ls /mnt/my_usb_stick
```

Ideally, you'd run a custom bash script that syncs stuff from your system to the drive.


### Safely eject the drive with `umount` and `cryptsetup close`

Always eject by unmounting the drive first, and then closing the partition conainer.
Order matters.

```sh
sudo umount /mnt/my_usb_stick
sudo cryptsetup close my_usb_stick
```

---

## 3. All Commands In One Go

To use an encrypted usb drive:

```sh
# 1. Unlock

sudo cryptsetup open /dev/sdb1 my_usb_stick
lsblk
sudo mount /dev/mapper/my_usb_stick /mnt/my_usb_stick
lsblk


# 2. Use the files in the drive


# 3. Lock

sudo umount /mnt/my_usb_stick
sudo cryptsetup close my_usb_stick

```

That is all.

