È possibile firmare un file usando un tasto ssh?


36

Uso SSH (OpenSSH 5.5p1 su Linux, per essere precisi). Ho una chiave su cui ho una passphrase. Lo uso per il solito accesso agli oggetti del computer.

Posso usarlo anche per firmare i file?

A quanto ho capito, una chiave SSH è una chiave RSA (o DSA) e durante il processo di accesso SSH, viene utilizzata per firmare i messaggi inviati al server. Quindi, in linea di principio e in pratica, può essere usato per firmare le cose - in effetti, questo è il suo unico scopo.

Ma per quanto posso vedere, non c'è modo di usare la chiave per firmare un file arbitrario (come faresti con PGP, diciamo). C'è un modo per farlo?


OpenSSH non utilizza Ed25519 come protocollo dati ? Sembra solo una questione di strumenti.
Pablo A

Risposte:


24

Potrebbe non esserci un modo per farlo solo con gli strumenti OpenSSH.

Ma può essere fatto abbastanza facilmente con gli strumenti OpenSSL. In effetti, ci sono almeno due modi per farlo. Negli esempi seguenti,~/.ssh/id_rsa è la tua chiave privata.

Un modo è usare dgst :

openssl dgst -sign ~/.ssh/id_rsa some-file

L'altro sta usando pkeyutl :

openssl pkeyutl -sign -inkey ~/.ssh/id_rsa -in some-file

Entrambi scrivono una firma binaria sullo standard output. dgst prende -hexun'opzione stamperà una rappresentazione testuale, con alcuni dettagli sulla forma della firma. pkeyutl prende -hexdumpun'opzione che è un po 'meno utile. Entrambi accettano chiavi RSA e DSA. Non ho idea di quale sia il formato dell'output. I due comandi producono formati diversi. Ho l'impressione che pkeyutl sia considerato più moderno di dgst .

Per verificare quelle firme:

openssl dgst -verify $PUBLIC_KEY_FILE -signature signature-file some-file

e:

openssl pkeyutl -verify -inkey $PUBLIC_KEY_FILE -sigfile signature-file -in some-file

Il problema qui è $PUBLIC_KEY_FILE. OpenSSL non può leggere il formato della chiave pubblica di OpenSSH, quindi non puoi semplicemente usarlo id_rsa.pub. Hai alcune opzioni, nessuna ideale.

Se hai una versione di OpenSSH di 5.6 o successive, apparentemente puoi farlo:

ssh-keygen -e -f ~/.ssh/id_rsa.pub -m pem

Che scriverà la chiave pubblica nell'output standard in formato PEM, che OpenSSL può leggere.

Se hai la chiave privata, ed è una chiave RSA, puoi estrarre la chiave pubblica da essa (presumo che il file della chiave privata con codifica PEM includa una copia della chiave pubblica, poiché non è possibile derivare la chiave pubblica dalla chiave privata stessa) e usa quello:

openssl rsa -in ~/.ssh/id_rsa -pubout

Non so se esiste un equivalente DSA. Si noti che questo approccio richiede una certa collaborazione da parte del proprietario della chiave privata, che dovrà estrarre la chiave pubblica e inviarla al potenziale verificatore.

Infine, puoi usare un programma Python scritto da un tipo chiamato Lars per convertire la chiave pubblica da OpenSSH in formato OpenSSL.


1
Vorrei solo notare che "non è possibile derivare la chiave pubblica dalla chiave privata stessa" non è vero. In pratica (cioè in tutti i sistemi crittografici effettivamente utilizzati) la chiave pubblica viene facilmente derivata dalla chiave privata per la maggior parte del tempo.
Kirelagin,

@kirelagin: non lo sapevo. Potresti dirmi, o collegarmi a, ulteriori informazioni su come si può fare?
Tom Anderson,

1
Non sono sicuro che ci siano delle letture particolari su questo argomento ... Pensiamo solo a questo. Prendi qualsiasi sistema crittografico discreto basato su log (ElGamal). In questo caso, la chiave privata è (dimensione del gruppo, generatore, potenza) e la chiave pubblica è (dimensione del gruppo, generatore, generatore ^ potenza). Quindi, il registro è difficile, ma il potere non lo è, basta calcolarlo.
Kirelagin,

Nel caso di RSA questa inversione è in realtà difficile, ma qui la situazione è leggermente diversa. La chiave pubblica è (n, d) e la chiave privata è (n, d ^ (- 1) mod phi (n)). Anche invertire d sarebbe difficile se non memorizzi phi (n), ma ecco il trucco: quasi tutti usano e = 65537 (quando generi una chiave c'è un'opzione per cambiare questa impostazione predefinita, ma non ho mai visto chiunque lo usi perché non ha alcun senso pratico), quindi derivare una chiave pubblica da una privata è banale.
Kirelagin,

Con le curve ellittiche è in realtà la stessa del log e della potenza discreti, invertire è facile. Detto questo, non sono sicuro di altri cryptosystems, ma quei tre sono quelli che vengono utilizzati nella pratica.
Kirelagin,

10

@ La risposta di Tom mi ha aiutato a iniziare, ma non ha funzionato immediatamente.

Questi comandi funzioneranno con:

  • OpenSSL 1.0.1 14 marzo 2012
  • OpenSSH_5.9p1

Usando pkeyutl

# openssl pkeyutl -sign -inkey ~/.ssh/id_sample -in $1 > $1.sig
# ssh-keygen -e -f ~/.ssh/id_sample.pub -m PKCS8 > pub
# openssl pkeyutl -verify -pubin -inkey pub -in $1 -sigfile $1.sig
Signature Verified Successfully

Usando dgst

# openssl dgst -sign ~/.ssh/id_sample $1 > $1.sig
# ssh-keygen -e -f ~/.ssh/id_sample.pub -m PKCS8 > pub
# openssl dgst -verify pub -signature $1.sig $1
Verified OK

La versione pkeyutl può firmare solo file di piccole dimensioni. Mentre dgst può firmare file di dimensioni arbitrarie, perché richiede un digest prima di firmare il risultato.


Anche per me la risposta di Stephen.z ha funzionato immediatamente. Prima ho continuato a giocare con la risposta di Tom per un po 'e alla fine ho trovato la risposta di Stephen.z che funzionava perfettamente con me. Grazie Stephen.z!
Grzegorz Wierzowiecki,


Hai provato a usare pkeyutl per firmare solo l'hash del file?
Gaia,

-3

Per verificare quelle firme - soluzione più semplice:

Il modo più semplice per assicurarsi che un documento firmato sia lo stesso, è rigenerare il file di firma digitale e quindi utilizzare diff per verificare se i due file di firma sono uguali.


3
Stai pensando agli hash , non alle firme . Simile, ma non uguale: l'hash verifica solo che il file non sia cambiato; una firma verifica anche da dove proviene.
Piskvor,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.