Apakah mungkin untuk menandatangani file menggunakan kunci ssh?

36

Saya menggunakan SSH (OpenSSH 5.5p1 di Linux, tepatnya). Saya memiliki kunci, di mana saya memiliki kata sandi. Saya menggunakan ini untuk login biasa ke barang-barang komputer.

Bisakah saya juga menggunakannya untuk menandatangani file?

Seperti yang saya pahami, kunci SSH adalah kunci RSA (atau DSA), dan selama proses login SSH, digunakan untuk menandatangani pesan yang dikirim ke server. Jadi pada prinsipnya dan dalam praktiknya, dapat digunakan untuk menandatangani sesuatu - memang, itulah satu-satunya tujuan.

Tapi sejauh yang saya bisa lihat, tidak ada cara untuk menggunakan kunci untuk menandatangani file yang sewenang-wenang (seperti yang Anda lakukan dengan PGP, katakan). Apakah ada cara untuk melakukan ini?

Tom Anderson
sumber
Bukankah OpenSSH menggunakan Ed25519 sebagai protokol dat ? Sepertinya hanya masalah alat.
Pablo A

Jawaban:

24

Mungkin tidak ada cara untuk melakukan ini dengan alat OpenSSH saja.

Tapi itu bisa dilakukan dengan mudah dengan alat OpenSSL. Faktanya, setidaknya ada dua cara untuk melakukannya. Dalam contoh di bawah ini, ~/.ssh/id_rsaadalah kunci pribadi Anda.

Salah satu caranya adalah menggunakan dgst :

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

Yang lainnya menggunakan pkeyutl :

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

Keduanya menulis tanda tangan biner ke output standar. dgst mengambil -hexopsi akan mencetak representasi tekstual, dengan beberapa detail tentang bentuk tanda tangan. pkeyutl mengambil -hexdumpopsi yang sedikit kurang berguna. Keduanya akan menerima kunci RSA dan DSA. Saya tidak tahu apa format outputnya. Dua perintah menghasilkan format yang berbeda. Saya mendapat kesan bahwa pkeyutl dianggap lebih modern daripada dgst .

Untuk memverifikasi tanda tangan itu:

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

dan:

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

Masalahnya di sini adalah $PUBLIC_KEY_FILE. OpenSSL tidak dapat membaca format kunci publik OpenSSH, jadi Anda tidak bisa hanya menggunakan id_rsa.pub. Anda memiliki beberapa opsi, tidak ada yang ideal.

Jika Anda memiliki versi OpenSSH 5.6 atau lebih baru, Anda dapat melakukannya:

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

Yang akan menulis kunci publik ke output standar dalam format PEM, yang dapat dibaca OpenSSL.

Jika Anda memiliki kunci pribadi, dan ini adalah kunci RSA, maka Anda dapat mengekstrak kunci publik darinya (saya berasumsi bahwa file kunci pribadi yang di-encode dengan PEM menyertakan salinan kunci publik, karena tidak mungkin untuk mendapatkan kunci publik dari kunci pribadi itu sendiri), dan gunakan itu:

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

Saya tidak tahu apakah ada yang setara dengan DSA. Perhatikan bahwa pendekatan ini memerlukan kerja sama dari pemilik kunci pribadi, yang harus mengekstrak kunci publik dan mengirimkannya ke calon verifikasi.

Terakhir, Anda dapat menggunakan program Python yang ditulis oleh chap bernama Lars untuk mengonversi kunci publik dari OpenSSH ke format OpenSSL.

Tom Anderson
sumber
1
Saya hanya ingin mencatat bahwa "tidak mungkin mendapatkan kunci publik dari kunci privat itu sendiri" tidak benar. Dalam praktiknya (yaitu, di semua cryptosystems yang benar-benar digunakan) kunci publik mudah diperoleh dari kunci privat sebagian besar waktu.
kirelagin
@kirelagin: Saya tidak tahu itu. Bisakah Anda memberi tahu saya, atau menautkan saya ke, informasi lebih lanjut tentang bagaimana hal itu dapat dilakukan?
Tom Anderson
1
Saya tidak yakin apakah ada bacaan khusus tentang topik ini ... Mari kita pikirkan saja. Ambil cryptosystem berbasis log diskrit (ElGamal). Dalam hal ini, kunci privat adalah (ukuran grup, generator, daya) dan kunci publik adalah (ukuran grup, generator, generator ^ daya). Jadi, log itu sulit, tetapi daya tidak, Anda hanya menghitungnya.
kirelagin
Dalam kasus RSA inversi ini sebenarnya sulit, tetapi di sini situasinya sedikit berbeda. Kunci publik adalah (n, d) dan kunci pribadi adalah (n, d ^ (- 1) mod phi (n)). Membalikkan d juga akan sulit jika Anda tidak menyimpan phi (n), tetapi inilah caranya: hampir semua orang menggunakan e = 65537 (ketika Anda menghasilkan kunci ada opsi untuk mengubah default ini, tapi saya belum pernah melihat siapa pun yang menggunakannya karena tidak masuk akal secara praktis), jadi memperoleh kunci publik dari kunci pribadi adalah sepele.
kirelagin
Dengan kurva Elliptic sebenarnya sama dengan log dan kekuatan diskrit, pembalikan mudah. Yang mengatakan, saya tidak yakin tentang cryptosystems lainnya, tetapi mereka adalah tiga yang digunakan dalam praktek.
kirelagin
10

Jawaban @ Tom membantu saya memulai, tetapi tidak berhasil.

Perintah-perintah ini akan bekerja dengan:

  • OpenSSL 1.0.1 14 Mar 2012
  • OpenSSH_5.9p1

Menggunakan 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

Menggunakan 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

Versi pkeyutl hanya dapat menandatangani file berukuran kecil. Sementara dgst dapat menandatangani file besar secara sewenang-wenang, karena butuh intisari sebelum menandatangani hasilnya.

stephen.z
sumber
Bagi saya juga, Stephen.z jawaban bekerja di luar kotak. Pertama saya terus bermain dengan jawaban Tom untuk sementara waktu dan akhirnya menemukan Stephen. Terima kasih Stephen.z!
Grzegorz Wierzowiecki
PS Di sini saya telah membagikan cuplikan saya: gist.github.com/gwpl/2c7636f0b200cbfbe82cc9d4f6338585
Grzegorz Wierzowiecki
Apakah Anda mencoba menggunakan pkeyutl untuk menandatangani hanya hash file?
Gaia
-3

Untuk memverifikasi tanda tangan tersebut - solusi yang lebih mudah:

Cara yang lebih mudah untuk memastikan dokumen yang ditandatangani adalah sama, adalah untuk menghasilkan kembali file tanda tangan digital dan kemudian menggunakan diff untuk memeriksa apakah kedua file tanda tangan itu sama.

Ehrhardt Le Grange
sumber
3
Anda berpikir tentang hash , bukan tanda tangan . Serupa, tetapi tidak sama: hash hanya memverifikasi bahwa file tidak berubah; tanda tangan juga memverifikasi dari mana datangnya.
Piskvor