IZ2VTW's Board

Creare un portachiavi perfetto per OpenGPG

3500 words - 17 min read

Questo articolo è un riassunto di vari articoli scovati su internet per creare un portachiavi per OpenGPG quasi perfetto.

Qui l’elenco degli articoli principali:

Nel caso tu non lo conosca, OpenPGP non è un semplice sistema per criptare e firmare messaggi, ma è un sistema per creare un’identità digitale che può essere verificata da altre persone in modo completamente decentralizzato. Non esiste un’unica entità centralizzata per il controllo delle identità: sono gli utenti a controllare gli altri utenti.

WARNING
Per favore, ricorda che sono un semplice utente e non uno specialista di crittografia. Questo è un semplice riassunto di diversi articoli trovati in giro per la rete. Il mondo della crittografia cambia rapidamente, ed è molto complesso. Utilizza questo articolo per una tua ricerca della perfezione.

Installare gli strumenti corretti

Per creare la coppia di chiavi perfetta per prima cosa si devono installare gli strumenti corretti:

  • Per Windows GPG4Win
  • Per MAC GPGtools
  • Per Linux GnuPG (Già installato nella maggioranza delle distribuzioni)

Configurare gli strumenti

Prima di partire è buona cosa configurare correttamente gli strumenti per aumentarne la sicurezza. Questa è una configurazione di OpenGPG per visualizzare più dati nell’elenco delle chiavi ed evitare perdite di informazioni sulla modalità di creazione della chiave. Alla fine del file ci sono alcune restrizioni sugli algoritmi di crittografia per utilizzare il migliore e il più resistente in questo momento. Siete liberi di copiare questo file in ~/.gnupg/gpg.conf (Linux e Mac) e C:\Users[username]\AppData\Roaming\gnupg\gpg.conf (Windows).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Avoid information leaked
no-emit-version
no-comments
export-options export-minimal

# Displays the long format of the ID of the keys and their fingerprints
#keyid-format 0xlong
with-fingerprint

# Displays the validity of the keys
list-options show-uid-validity
verify-options show-uid-validity

# Limits the algorithms used
personal-cipher-preferences AES256
personal-digest-preferences SHA512
default-preference-list SHA512 SHA384 SHA256 RIPEMD160 AES256 TWOFISH BLOWFISH ZLIB BZIP2 ZIP Uncompressed

cipher-algo AES256
digest-algo SHA512
cert-digest-algo SHA512
compress-algo ZLIB

disable-cipher-algo 3DES
weak-digest SHA1

s2k-cipher-algo AES256
s2k-digest-algo SHA512
s2k-mode 3
s2k-count 65011712

Inizia a sfruttare il vantaggio delle sottochiavi

Quando si crea una chiave con OpenPGP in modalità base, verrà creata una coppia di chiavi per firmare e certificare. Se la chiave privata viene rubata o persa, tutta la tua identità digitale viene compromessa. Per aumentare la sicurezza della tua coppia di chiavi è possibile utilizzare una funzione presente in OpenPGP: le sottochiavi.

OpenPGP ti consente di creare diverse sottochiavi con un compito specifico: crittografare, firmare e autenticarsi. Se si memorizza correttamente la chiave principale (quella utilizzata per certificare le altre chiavi) in un posto sicuro, e viene rubata una delle sottochiavi, l’unica chiave da revocare è la sottochiave non sicura e la propria identità (la chiave principale) rimane sicura.

Crea la tua identità digitale

Iniziamo creando la chiave principale. Questa chiave conterrà l’identità. Per utilizzare la funzione delle sottochiavi di OpenPGP è necessario creare la chiave di certificazione per il Doctor Who. Questo permetterà di certificare altre chiavi. È una chiave speciale e molto importante, è necessario conservarla in sicurezza.

NOTA IMPORTANTE
Quando si crea la nuova coppia di chiavi, è necessario utilizzare i valori più alti possibili per la lunghezza della chiave. Lo spazio di archiviazione oggi è economico e un messaggio oggi indecifrabile potrebbe essere decifrato nel prossimo futuro da un computer più potente. Per favore, non usare il valore predefinito GPG di 2048bit!
INFO
L’output dei comandi riportato può essere diverso dal tuo. La possibile differenza è dovuta alla versione diversa o all’output troncato per adattarsi alla pagina.
doctor@tardis:~$ gpg2 --expert --full-gen-key
gpg (GnuPG) 2.1.11; Copyright (C) 2016 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: keybox '/home/doctor/.gnupg/pubring.kbx' created
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC and ECC
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Wed Apr  3 22:40:20 2019 CEST
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: Doctor Who
E-mail address: doctor@tardis.net
Comment:
You selected this USER-ID:
    "Doctor Who <doctor@tardis.net>"

Change (N)ame, (C)omment, (E)-mail or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilise the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /home/doctor/.gnupg/trustdb.gpg: trustdb created
gpg: key FD8607C7 marked as ultimately trusted
gpg: directory '/home/doctor/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/doctor/.gnupg/openpgp-revocs.d/20522982307DF46E5A31ACA808E72BD1FD8607C7.rev'
public and secret key created and signed.

gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: PGP
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2019-04-03
pub   rsa4096/FD8607C7 2018-04-03 [] [expires: 2019-04-03]
      Key fingerprint = 2052 2982 307D F46E 5A31  ACA8 08E7 2BD1 FD86 07C7
uid         [ultimate] Doctor Who <doctor@tardis.net>

Se noti che la validità della chiave è impostata su 1 anno per evitare problemi in caso di perdita del certificato di revoca (lo hai memorizzato in modo sicuro?) e per restare in allenamento con OpenPGP. Bene, adesso abbiamo creato la coppia di chiavi master. Ora creiamo le sottochiavi.

Creare le sottochiavi

Adesso con la chiave principale inizia la parte più importante della creazione del portachiavi: La creazione delle sottochiavi. Le sottochiavi da creare sono 3:

  1. Autenticazione (A)
  2. Firma (S)
  3. Crittografia (E)

Procediamo con la creazione, andiamo! Per prima cosa elenchiamo le chiavi già presenti:

doctor@tardis:~$ gpg2 --list-keys
/home/doctor/.gnupg/pubring.kbx
---------------------------------
pub   rsa4096/FD8607C7 2018-04-03 [C] [expires: 2019-04-03]
      Key fingerprint = 2052 2982 307D F46E 5A31  ACA8 08E7 2BD1 FD86 07C7
uid         [ultimate] Doctor Who <doctor@tardis.net>

Ok, la chiave principale è presente. Ora editiamola per aggiungere le sottochiavi. Per fare ciò è il momento di passare alla modalià expert mode.

doctor@tardis~$ gpg2 --expert --edit-key FD8607C7
gpg (GnuPG) 2.1.11; Copyright (C) 2016 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/FD8607C7
     created: 2018-04-03  expires: 2019-04-03  usage: C
     trust: ultimate      validity: ultimate
[ultimate] (1). Doctor Who <doctor@tardis.net>

gpg>

Ora sei in modalità di editing. Aggiungiamo la chiave per la crittografia con il comando addkey.

gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Wed Apr  3 22:42:16 2019 CEST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  rsa4096/FD8607C7
     created: 2018-04-03  expires: 2019-04-03  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/11D8D5C0
     created: 2018-04-03  expires: 2019-04-03  usage: E
[ultimate] (1). Doctor Who <doctor@tardis.net>

gpg>

La chiave con l’impronta 11D8D5C0 è stata creata. Ripetere per le chiave di Firma e Autenticazione. Alla fine, si avranno le seguenti chiavi:

sec  rsa4096/FD8607C7
     created: 2018-04-03  expires: 2019-04-03  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/11D8D5C0
     created: 2018-04-03  expires: 2019-04-03  usage: E
ssb  rsa4096/9B825FCF
     created: 2018-04-03  expires: 2019-04-03  usage: S
ssb  rsa4096/5E6B1035
     created: 2018-04-03  expires: 2019-04-03  usage: A
[ultimate] (1). Doctor Who <doctor@tardis.net>

gpg> save

Digita save e quindi quit, e siamo a posto. Adesso il Dottore ha una coppia di chiavi OpenGPG per gestire la sua identità digitale e le sottochiavi per gesitre le differenti azioni.

Prima di continuare a fare qualsiasi cosa è importante effettuare un robusto backup.

Esportare le chiavi per la conservazione a lungo termine

La chiave PGP non è sicura per essere utilizzata in questo momento. In caso di evento di furto della chiave principale e della password, il ladro sarebbe in grado di impersonare l’identità digitale completamente. La chiave principale, che permette la certificazione, deve essere costudita in uno spazio di archiviazione disconnesso dalla rete.

Per prima cosa si deve creare uno spazio di archiviazione per i file temporanei sulla propria macchina:

mkdir /tmp/gpg
sudo mount -t ramfs -o size=10M ramfs /tmp/gpg
sudo chown $(logname):$(logname) /tmp/gpg

Primo, per evitare un utilizzo non autorizzato della coppia di chiavi, creiamo un certificato di revoca:

doctor@tardis:~$ gpg2 --output /tmp/gpg/FD8607C7.rev --gen-revoke FD8607C7

sec  rsa4096/FD8607C7 2018-04-03 Doctor Who <doctor@tardis.net>

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 1
Enter an optional description; end it with an empty line:
>
Reason for revocation: Key has been compromised
(No description given)
Is this okay? (y/N) y
ASCII armoured output forced.
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The print system of
your machine might store the data and make it available to others!

Ora presta attenzione a questo file. Questo file va mantenuto in un posto sicuro per prevenire il suo uso per il blocco nella nostra identità: in questo caso si dovrà poi provvedere a ricreare da zero tutta la nostra catena di fiducia. Adesso esportiamo tutte le chiavi per preparare il portachiavi per l’uso quotidiano.

doctor@tardis:~$ gpg2 --export --armor FD8607C7 > /tmp/gpg/FD8607C7.pub.asc
doctor@tardis:~$ gpg2 --export-secret-keys --armor FD8607C7 > /tmp/gpg/FD8607C7.priv.asc
doctor@tardis:~$ gpg2 --export-secret-subkeys --armor FD8607C7 > /tmp/gpg/FD8607C7.sub_priv.asc

Adesso FD8607C7.pub.asc contiene tutte la chiave pubblica e FD8607C7.priv.asc la chiave privata della coppia principale. FD8607C7.sub_priv.asc contiene solo le chiavi private delle sotto chiavi.

Cancellare la chiave privata principale

Come menzionato sopra il portachiavi per uso quotidiano non contiene la chiave privata principale. Ora cancelliamo la chiave privata principale:

doctor@tardis:~$ gpg2 --delete-secret-key FD8607C7
gpg (GnuPG) 2.1.11; Copyright (C) 2016 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


sec  rsa4096/FD8607C7 2018-04-03 Doctor Who <doctor@tardis.net>

Delete this key from the keyring? (y/N) y
This is a secret key! - really delete? (y/N) y

E ora re-importiamo solo le sotto chiavi:

doctor@tardis:~$ gpg2 --import /tmp/gpg/FD8607C7.sub_priv.asc
gpg: key FD8607C7: "Doctor Who <doctor@tardis.net>" not changed
gpg: To migrate 'secring.gpg', with each smartcard, run: gpg --card-status
gpg: key FD8607C7: secret key imported
gpg: Total number processed: 5
gpg:              unchanged: 1
gpg:       secret keys read: 5
gpg:   secret keys imported: 3

Dopo aver re-importato solo le sotto chiavi è il momento di controllare la corretta importazione:

doctor@tardis:~$ gpg2 --list-secret-keys
/home/doctor/.gnupg/pubring.kbx
---------------------------------
sec#  rsa4096/FD8607C7 2018-04-03 [C] [expires: 2019-04-03]
      Key fingerprint = 2052 2982 307D F46E 5A31  ACA8 08E7 2BD1 FD86 07C7
uid         [ultimate] Doctor Who <doctor@tardis.net>
ssb   rsa4096/11D8D5C0 2018-04-03 [E] [expires: 2019-04-03]
ssb   rsa4096/9B825FCF 2018-04-03 [S] [expires: 2019-04-03]
ssb   rsa4096/5E6B1035 2018-04-03 [A] [expires: 2019-04-03]

Il simbolo # dopo sec indica che la chiave privata principale non è più presente nel portachiavi.

Ora il portachiavi è pronto per l’uso quotidiano, ora tutti i file creati vanno mantenuti off-line. Nella prossima sezione vedremo come creare una copia sicura offline.

Creare una copia offline sicura

OK, adesso abbiamo un portachiavi perfetto, ma come conservare in modo sicuro la chiave privata principale?

Ovviamente la chiave privata non è sicura mantenendola sul computer utilizzato quotidianamente. Va conservata in uno spazio offline, completamente disonnesso dalla rete. I possibili supporti sono:

  • Chiavetta USB
  • Hard Disk esterno
  • disco ottico
  • nastro magnetico
  • carta
  • pietra

Ma non tutti sono sicuri come gli altri. Il primo criterio per scegliere il supporto migliore è quello che dura di più nel tempo.

I supporti digitali non hanno una durata infinita.

Se scrivo i dati su un supporto sono sicuro che i dati sono scritti correttamente adesso, e voglio essere sicuro che anche tra 20 anni i dati siano leggibili ancora. Sui suporti ottici il tempo di stoccaggio è di 15 anni, su una chiavetta USB il problema è la tecnologia: il dato è salvato come una carica elettrica nella cella, la mancanza di aggiornamento farà degradare il dato.

L’altro problema è la gestione del supporto: pensa agli HD-DVD. Questo supporto è stato usato 10 anni fa, ma adesso è praticamente impossibile trovare un HW atto a leggere questo supporto (sugli ultimi PC non è più presente neanche il lettore DVD).

Seguendo questo criterio la conservazione in digitale non è una buona scelta. OK, mettiamo la chiave su un supporto non digitale: carta o pietra. Per convenienza sceglieremo la carta.

Il problema è la lunghezza della chiave (4096bit). La semplice stampa della chiave potrebbe portare a un problema nel momento in cui si dovrà reinserire la chiave manualmente. Questa operazione ha già un alto errore intrinseco, e i software OCR possono incorrere in errori nel riconoscere la O (O in maiusclo) e lo 0 (zero) per esempio.

Qui alcuni “trucchi” per ridurre il problema:

  • Usare un codice 2D (QR code, Data Matrix) per una conservazione a breve termine
  • Stampare un dump dei dati con un checksum per una conservazione a più lungo termine

Stampa del dump esadecimale con CRC

Qui è presente uno script python che permette di avere un dump esadecimale con un checksum per ogni riga del file esportato.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

def crc32(buf, crc=0xFFFFFFFF):
    for c in buf:
        crc = crc ^ ord(c)
        for i in range(8):
            if crc & 1:
                crc = (crc >> 1) ^ 0xedb88320
            else:
                crc = crc >> 1;
    return crc ^ 0xFFFFFFFF;

offset = 0
with open(sys.argv[1]) as fp:
    for chunk in iter(lambda: fp.read(16), b''):
        if chunk:
            cksum = crc32(chunk)
            dump = ' '.join('{:02X}'.format(ord(a)) for a in chunk)
            print("%08X | %-47s | %08X | %s" % (offset, dump, cksum, repr(chunk)))
            offset = offset + len(chunk)
        else:
            break
    print("%08X" % offset)
    fp.close()

Qui i vari passi dello script:

  • legge il file in blocchi da 16 byte
  • stampa il dump esadecimale
  • per ogni linea visualizza la riga in ASCII e genera il checksum della parte raw di ogni riga

Stampa di esempio:

00000000 | 2D 2D 2D 2D 2D 42 45 47 49 4E 20 50 47 50 20 50 | 4BDAE384 | '-----BEGIN PGP P'
00000010 | 55 42 4C 49 43 20 4B 45 59 20 42 4C 4F 43 4B 2D | E312478B | 'UBLIC KEY BLOCK-'
00000020 | 2D 2D 2D 2D 0A 0A 6D 51 49 4E 42 46 72 44 57 69 | 8195F9F3 | '----\n\nmQINBFrDWi'
00000030 | 34 42 45 41 44 53 44 73 32 54 79 74 33 4B 42 63 | 3A009DA6 | '4BEADSDs2Tyt3KBc'
00000040 | 4B 65 4F 70 77 5A 4B 70 4E 76 61 56 35 74 73 31 | 1ED1B1EA | 'KeOpwZKpNvaV5ts1'

Prendiamo la prima linea ad esempio. Da sinistra a destra:

  • indice del primo byte della linea
  • 16 gruppi di 2 caratteri esadecimali. Ogni grupo rappresenta un carattere ASCII
  • il checksum CRC32 dei valori ASCII
  • I caratteri ASCII con i caratteri con escape

Ripristinare il file

Adesso il problema è controllare la correttezza nel ripristino del file salvato. L’inserimanto manuale è lungo e spesso è difficile trovare gli errori. I programmi OCR, come già scritto, possono presentare errori con il riconoscimento di alcune lettere. Qui è riportato un semplice script python per ripristinare i dati da un input manuale o uno scan OCR con la notifica degli errori. Dopo una correzione degli errori verrà stampato il file originale.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    #!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

def crc32(buf, crc=0xFFFFFFFF):
    for c in buf:
        crc = crc ^ ord(c)
        for i in range(8):
            if crc & 1:
                crc = (crc >> 1) ^ 0xedb88320
            else:
                crc = crc >> 1;
    return crc ^ 0xFFFFFFFF;

data = []
with open(sys.argv[1]) as fp:
    for line in fp:
        data.append({
            'offset': line[0:8],
            'value': line[11:58].split(),
            'cksum': line[61:69],
            'string': line[72:(line.rfind("'")+1)]
        })
    fp.close()

ascFile = ""
offset = 0
for chunk in data:
    chunkValue = ""
    for hexdump in chunk['value']:
        chunkValue = chunkValue + (chr(int(hexdump, 16)))
    if (chunk['cksum'] != ''):
        if crc32(chunkValue) == int(chunk['cksum'], 16):
            ascFile = ascFile + chunkValue
            offset = len(ascFile)
        else:
            print("Checksum error at line: " + chunk['offset'])
            restored = repr(chunkValue)
            diff = ""
            for i in range(len(restored)):
                if restored[i] == chunk['string'][i]:
                    diff = diff + "·"
                else:
                    diff = diff + "X"
            print("HEX: %s | ASCII: %s | DIFF: %s" % (restored, chunk['string'], diff))
            sys.exit(1)
    else:
        if offset == int(chunk['offset'], 16):
            print(ascFile)
        else:
            print("File length error!!!!")
            sys.exit(2)

Per garantire che il backup perfetto sia OK ora è il momento di effettuare un test. Ottieni il dump stampato con il codice QR e controlla la lettura corretta senza differenza nei 2 file.

Dopo questo semplice test ora prendi molto tempo e una tazza di tè e copia a mano tutti i file, o semplicemente scansiona il dump stampato e usando un software OCR (es. Tesseract) leggi l’immagine. Successivamente, passa il file allo script sopra e controlla il file.

Conclusione

Attraverso questo articolo, abbiamo creato una chiave PGP master con una serie di sottochiavi dedicate a un determinato compito. Il vantaggio di questa funzione è che non è necessario revocare la chiave principale, quella che detiene la nostra identità digitale, nel caso di compromissione. Questa strategia offre un livello di sicurezza molto più elevato.

Penso che in un prossimo post proverò a spiegare la parte dei Signing party e l’uso di una chiave hardware.

Updated: 2020-04-10 17:23:59 +0200 +0200 - Modifica la pagina
Commit: ":sparkles: Add Creating perfect keypair in Italian" [bc7d7a3]
By: Francesco Vezzoli <fvezzoli@villavasco.ovh>