Ist es möglich, eine Datei mit einem SSH-Schlüssel zu signieren?

36

Ich benutze SSH (OpenSSH 5.5p1 unter Linux, um genau zu sein). Ich habe einen Schlüssel, auf dem ich eine Passphrase habe. Ich benutze dies für die übliche Anmeldung an Computern Sachen.

Kann ich damit auch Dateien signieren?

Soweit ich weiß, ist ein SSH-Schlüssel ein RSA- (oder DSA-) Schlüssel und wird während des SSH-Anmeldevorgangs zum Signieren von Nachrichten verwendet, die an den Server gesendet werden. Im Prinzip und in der Praxis kann es also verwendet werden, um Dinge zu signieren - in der Tat ist dies der einzige Zweck.

Aber soweit ich sehen kann, gibt es keine Möglichkeit, mit dem Schlüssel eine beliebige Datei zu signieren (wie Sie es beispielsweise mit PGP tun würden). Gibt es eine Möglichkeit, dies zu tun?

Tom Anderson
quelle
Verwendet OpenSSH nicht Ed25519 als dat-Protokoll ? Scheint nur eine Frage von Werkzeugen.
Pablo A

Antworten:

24

Möglicherweise gibt es keine Möglichkeit, dies nur mit den OpenSSH-Tools zu tun.

Mit den OpenSSL-Tools ist dies jedoch recht einfach möglich. Tatsächlich gibt es mindestens zwei Möglichkeiten, dies zu tun. In den folgenden Beispielen ~/.ssh/id_rsaist dies Ihr privater Schlüssel.

Eine Möglichkeit ist die Verwendung von dgst :

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

Der andere benutzt pkeyutl :

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

Beide schreiben eine binäre Signatur in die Standardausgabe. Wenn dgst eine -hexOption wählt, wird eine Textdarstellung mit einigen Details zur Form der Signatur gedruckt. pkeyutl verwendet eine -hexdumpOption, die etwas weniger nützlich ist. Beide akzeptieren sowohl RSA- als auch DSA-Schlüssel. Ich habe keine Ahnung, welches Format die Ausgabe hat. Die beiden Befehle erzeugen unterschiedliche Formate. Ich habe den Eindruck, dass pkeyutl als moderner gilt als dgst .

So überprüfen Sie diese Signaturen:

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

und:

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

Das Problem ist hier $PUBLIC_KEY_FILE. OpenSSL kann das öffentliche Schlüsselformat von OpenSSH nicht lesen, Sie können es also nicht einfach verwenden id_rsa.pub. Sie haben ein paar Möglichkeiten, keine ideal.

Wenn Sie eine OpenSSH-Version von 5.6 oder höher haben, können Sie dies anscheinend tun:

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

Damit wird der öffentliche Schlüssel in die Standardausgabe im PEM-Format geschrieben, die OpenSSL lesen kann.

Wenn Sie den privaten Schlüssel haben und es sich um einen RSA-Schlüssel handelt, können Sie den öffentlichen Schlüssel daraus extrahieren (ich gehe davon aus, dass die PEM-codierte private Schlüsseldatei eine Kopie des öffentlichen Schlüssels enthält, da es nicht möglich ist, den öffentlichen Schlüssel abzuleiten vom privaten Schlüssel selbst), und verwenden Sie Folgendes:

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

Ich weiß nicht, ob es ein DSA-Äquivalent gibt. Beachten Sie, dass dieser Ansatz eine gewisse Zusammenarbeit des Besitzers des privaten Schlüssels erfordert, der den öffentlichen Schlüssel extrahieren und an den potenziellen Prüfer senden muss.

Zuletzt können Sie ein Python-Programm verwenden, das von einem Jungen namens Lars geschrieben wurde , um den öffentlichen Schlüssel von OpenSSH in das OpenSSL-Format zu konvertieren.

Tom Anderson
quelle
1
Ich möchte nur bemerken, dass "es nicht möglich ist, den öffentlichen Schlüssel vom privaten Schlüssel selbst abzuleiten", ist nicht wahr. In der Praxis (dh in allen tatsächlich verwendeten Kryptosystemen) wird der öffentliche Schlüssel die meiste Zeit problemlos vom privaten Schlüssel abgeleitet.
Kirelagin
@kirelagin: Das wusste ich nicht. Können Sie mir weitere Informationen darüber geben oder mich verlinken, wie dies möglich ist?
Tom Anderson
1
Ich bin mir nicht sicher, ob es zu diesem Thema eine bestimmte Lektüre gibt. Nehmen Sie ein beliebiges diskretes logbasiertes Kryptosystem (ElGamal). In diesem Fall ist der private Schlüssel (Gruppengröße, Generator, Leistung) und der öffentliche Schlüssel (Gruppengröße, Generator, Generatorleistung). Logbuch ist also schwierig, aber Macht ist es nicht, man berechnet es einfach.
Kirelagin
Im Falle von RSA ist diese Inversion tatsächlich schwierig, aber hier ist die Situation etwas anders. Der öffentliche Schlüssel ist (n, d) und der private Schlüssel ist (n, d ^ (- 1) mod phi (n)). Das Invertieren von d wäre auch schwierig, wenn Sie phi (n) nicht gespeichert hätten, aber hier ist der Trick: Fast jeder verwendet e = 65537 (wenn Sie einen Schlüssel generieren, gibt es eine Option, diese Standardeinstellung zu ändern, aber ich habe sie noch nie gesehen Jeder, der es verwendet, weil es praktisch keinen Sinn ergibt. Es ist daher trivial, einen öffentlichen Schlüssel von einem privaten abzuleiten.
Kirelagin
Mit elliptischen Kurven ist es tatsächlich dasselbe wie mit diskretem Log und diskreter Leistung, das Invertieren ist einfach. Allerdings bin ich mir bei anderen Kryptosystemen nicht sicher, aber diese drei werden in der Praxis verwendet.
Kirelagin
10

@Toms Antwort hat mir den Einstieg erleichtert, hat aber nicht sofort funktioniert.

Diese Befehle funktionieren mit:

  • OpenSSL 1.0.1 14. März 2012
  • OpenSSH_5.9p1

Pkeyutl verwenden

# 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

Mit 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

Die pkeyutl-Version kann nur kleine Dateien signieren. Dgst kann zwar beliebig große Dateien signieren, da es einen Digest benötigt, bevor das Ergebnis signiert wird.

stephen.z
quelle
Zu mir hat auch Stephen.z Antwort out-of-the-box geklappt. Zuerst spielte ich eine Weile mit Toms Antwort und fand schließlich Stephen.z Antwort, die perfekt zu mir passte. Danke Stephen.z!
Grzegorz Wierzowiecki
PS Hier habe ich meine Schnipsel geteilt: gist.github.com/gwpl/2c7636f0b200cbfbe82cc9d4f6338585
Grzegorz Wierzowiecki
Haben Sie versucht, mit pkeyutl nur den Hash der Datei zu signieren?
Gaia
-3

So überprüfen Sie diese Signaturen - einfachere Lösung:

Eine einfachere Möglichkeit, sicherzustellen, dass ein signiertes Dokument identisch ist, besteht darin, die digitale Signaturdatei erneut zu generieren und anschließend mithilfe von diff zu überprüfen, ob die beiden Signaturdateien identisch sind.

Ehrhardt Le Grange
quelle
3
Sie denken an Hashes , nicht an Signaturen . Ähnlich, aber nicht gleich: Der Hash überprüft nur, dass sich die Datei nicht geändert hat. Eine Unterschrift bestätigt auch, woher sie stammt.
Piskvor 20.10.11