feat: security - gnupg & openssh's KDF

This commit is contained in:
Ryan Yin
2024-01-26 12:38:13 +08:00
parent ec5ef05983
commit ecc335b07e
12 changed files with 155 additions and 25 deletions

View File

@@ -0,0 +1,14 @@
# Encryption
We have GnuPG & password-store installed by default, mainly for password management, authentication & communication encryption.
We also have LUKS2 for disk encryption on Linux, and [rclone](https://rclone.org/crypt/) for cross-platform data encryption & syncing.
[Age](https://github.com/FiloSottile/age) may be more general for file encryption.
[Sops](https://github.com/getsops/sops/tree/main) can be used for file encryption too, if you prefer
using a Cloud provider for key management.
TODO

View File

@@ -0,0 +1,7 @@
{pkgs, ...}: {
home.packages = with pkgs; [
age
sops
rclone
];
}

View File

@@ -42,6 +42,44 @@ To use GnuGP without seamlessly, Some Practical Cryptography knowledge is requir
> ArchWiki's GnuPG page: <https://wiki.archlinux.org/title/GnuPG>
### 0. How GnuGP generate & protect your keypair?
Related Docs:
- [Predictable, Passphrase-Derived PGP Keys](https://nullprogram.com/blog/2019/07/10/)
- [OpenPGP - The almost perfect key pair](https://blog.eleven-labs.com/en/openpgp-almost-perfect-key-pair-part-1/)
GnuPG generate every secret key separately, and encrypt them with a symmetric key derived from your passphrase.
OpenPGP standard defines [String-to-Key (S2K)](https://datatracker.ietf.org/doc/html/rfc4880#section-3.7)
algorithm to derive a symmetric key from your passphrase.
GnuPG's [OpenPGP protocol specific options](https://gnupg.org/documentation/manuals/gnupg/OpenPGP-Options.html#OpenPGP-Options) shows that:
```
--s2k-cipher-algo name
Use name as the cipher algorithm for symmetric encryption with a passphrase if --personal-cipher-preferences and --cipher-algo are not given. The default is AES-128.
--s2k-digest-algo name
Use name as the digest algorithm used to mangle the passphrases for symmetric encryption. The default is SHA-1.
--s2k-mode n
Selects how passphrases for symmetric encryption are mangled. If n is 0 a plain passphrase (which is in general not recommended) will be used, a 1 adds a salt (which should not be used) to the passphrase and a 3 (the default) iterates the whole process a number of times (see --s2k-count).
--s2k-count n
Specify how many times the passphrases mangling for symmetric encryption is repeated. This value may range between 1024 and 65011712 inclusive. The default is inquired from gpg-agent. Note that not all values in the 1024-65011712 range are legal and if an illegal value is selected, GnuPG will round up to the nearest legal value. This option is only meaningful if --s2k-mode is set to the default of 3.
```
The strongest options should be:
```
gpg --s2k-mode 3 --s2k-count 65011712 --s2k-digest-algo SHA512 --s2k-cipher-algo AES256 ...
```
To use the strongest options globally, you can add the following lines to your `~/.gnupg/gpg.conf`.
I've added them to my Home Manager's `programs.gpg.settings` option.
### 1. PGP Key(Primary Key) generation
Key management is the core of OpenPGP standard / GnuPG.

View File

@@ -24,7 +24,60 @@
trust = 5;
} # ultimate trust, my own keys.
];
# This configuration is based on the tutorial below, it allows for a robust setup
# https://blog.eleven-labs.com/en/openpgp-almost-perfect-key-pair-part-1
# ~/.gnupg/gpg.conf
settings = {
# Get rid of the copyright notice
no-greeting = true;
# Disable inclusion of the version string in ASCII armored output
no-emit-version = true;
# Do not write comment packets
no-comments = false;
# Export the smallest key possible
# This removes all signatures except the most recent self-signature on each user ID
export-options = "export-minimal";
# Display long key IDs
keyid-format = "0xlong";
# List all keys (or the specified ones) along with their fingerprints
with-fingerprint = true;
# Display the calculated validity of user IDs during key listings
list-options = "show-uid-validity";
verify-options = "show-uid-validity show-keyserver-urls";
# Select the strongest cipher
personal-cipher-preferences = "AES256";
# Select the strongest digest
personal-digest-preferences = "SHA512";
# This preference list is used for new keys and becomes the default for "setpref" in the edit menu
default-preference-list = "SHA512 SHA384 SHA256 RIPEMD160 AES256 TWOFISH BLOWFISH ZLIB BZIP2 ZIP Uncompressed";
# Use the strongest cipher algorithm
cipher-algo = "AES256";
# Use the strongest digest algorithm
digest-algo = "SHA512";
# Message digest algorithm used when signing a key
cert-digest-algo = "SHA512";
# Use RFC-1950 ZLIB compression
compress-algo = "ZLIB";
# Disable weak algorithm
disable-cipher-algo = "3DES";
# Treat the specified digest algorithm as weak
weak-digest = "SHA1";
# The cipher algorithm for symmetric encryption for symmetric encryption with a passphrase
s2k-cipher-algo = "AES256";
# The digest algorithm used to mangle the passphrases for symmetric encryption
s2k-digest-algo = "SHA512";
# Selects how passphrases for symmetric encryption are mangled
s2k-mode = "3";
# Specify how many times the passphrases mangling for symmetric encryption is repeated
s2k-count = "65011712";
};
};
}

View File

@@ -78,10 +78,6 @@
# productivity
caddy # A webserver with automatic HTTPS via Let's Encrypt(replacement of nginx)
croc # File transfer between computers securely and easily
# security
age
sops
];
programs = {

View File

@@ -12,9 +12,20 @@
users.users.${username} = {
description = userfullname;
# Public Keys that can be used to login to all my PCs, Macbooks, and servers.
#
# Since its authority is so large, we must strengthen its security:
# 1. The corresponding private key must be:
# 1. Generated locally on every trusted client via:
# ```bash
# # KDF: bcrypt with 256 rounds, takes 2s on Apple M2):
# # Passphrase: digits + letters + symbols, 12+ chars
# ssh-keygen -t ed25519 -a 256 -C "ryan@xxx" -f ~/.ssh/xxx`
# ```
# 2. Never leave the device and never sent over the network.
# 2. Or just use hardware security keys like Yubikey/CanoKey.
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDiipi59EnVbi6bK1bGrcbfEM263wgdNfbrt6VBC1rHx ryan@ai-idols"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMSfp/hvegbK04HykWvoY1EbDW+vXu1AlCjVivWE2ZeR ryan@shoukei"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE400EbKY1D9zfevk17AaPTtQ8dxJvCS5Zec+8aleLY4 ryan@fern"
];
};

View File

@@ -1,6 +0,0 @@
{
imports = [
./base
../base.nix
];
}

View File

@@ -0,0 +1,7 @@
{username, ...}: {
# Public Keys that can be used to login to all my servers.
users.users.${username}.openssh.authorizedKeys.keys = [
# TODO update keys here
"ssh-ed25519 xxx ryan@romantic"
];
}

View File

@@ -4,11 +4,13 @@
# =========================================================================
imports = [
./base/i18n.nix
./base/misc.nix
./base/user-group.nix
../base/i18n.nix
../base/misc.nix
../base/user-group.nix
../base.nix
../../base.nix
./security.nix
];
# List packages installed in system profile. To search, run:

View File

@@ -0,0 +1,8 @@
{
imports = [
../base
../../base.nix
./security.nix
];
}

View File

@@ -44,8 +44,8 @@ in {
idol_aquamarine_modules = {
nixos-modules = [
../hosts/idols_aquamarine
../modules/nixos/server.nix
../modules/nixos/proxmox-hardware-configuration.nix
../modules/nixos/server/server.nix
../modules/nixos/server/proxmox-hardware-configuration.nix
];
home-module.imports = [
../hosts/idols_aquamarine/home.nix
@@ -58,8 +58,8 @@ in {
idol_ruby_modules = {
nixos-modules = [
../hosts/idols_ruby
../modules/nixos/server.nix
../modules/nixos/proxmox-hardware-configuration.nix
../modules/nixos/server/server.nix
../modules/nixos/server/proxmox-hardware-configuration.nix
];
home-module.imports = [
../hosts/idols_ruby/home.nix
@@ -72,8 +72,8 @@ in {
idol_kana_modules = {
nixos-modules = [
../hosts/idols_kana
../modules/nixos/server.nix
../modules/nixos/proxmox-hardware-configuration.nix
../modules/nixos/server/server.nix
../modules/nixos/server/proxmox-hardware-configuration.nix
];
home-module.imports = [
../hosts/idols_kana/home.nix
@@ -86,7 +86,7 @@ in {
rolling_nozomi_modules = {
nixos-modules = [
../hosts/rolling_girls_nozomi
../modules/nixos/server-riscv64.nix
../modules/nixos/server/server-riscv64.nix
# cross-compilation this flake.
{nixpkgs.crossSystem.system = "riscv64-linux";}
@@ -99,7 +99,7 @@ in {
rolling_yukina_modules = {
nixos-modules = [
../hosts/rolling_girls_yukina
../modules/nixos/server-riscv64.nix
../modules/nixos/server/server-riscv64.nix
# cross-compilation this flake.
{nixpkgs.crossSystem.system = "riscv64-linux";}
@@ -112,7 +112,7 @@ in {
_12kingdoms_suzu_modules = {
nixos-modules = [
../hosts/12kingdoms_suzu
../modules/nixos/server-riscv64.nix
../modules/nixos/server/server-riscv64.nix
# cross-compilation this flake.
{nixpkgs.crossSystem.config = "aarch64-unknown-linux-gnu";}