Чи можливо підписати файл за допомогою ключа ssh?


36

Я використовую SSH (OpenSSH 5.5p1 для Linux, якщо бути точним). У мене є ключ, на якому я маю парольну фразу. Я використовую це для звичайного входу в комп'ютер.

Чи можу я також використовувати його для підписання файлів?

Як я розумію, ключ SSH - це ключ RSA (або DSA), і під час процесу входу в SSH він використовується для підписання повідомлень, що надсилаються на сервер. Так що в принципі і на практиці його можна використовувати для підписання речей - справді це єдина його мета.

Але наскільки я бачу, немає ніякого способу використовувати ключ для підписання довільного файлу (як, наприклад, з PGP). Чи є якийсь спосіб це зробити?


Чи OpenSSH не використовує Ed25519 як протокол DAT ? Здається, лише питання інструментів.
Пабло А

Відповіді:


24

Можливо, не існує способу зробити це лише за допомогою інструментів OpenSSH.

Але це можна зробити досить легко за допомогою інструментів OpenSSL. Насправді, принаймні два способи це зробити. У прикладах нижче - ~/.ssh/id_rsaце ваш приватний ключ.

Один із способів використання dgst :

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

Інший використовує pkeyutl :

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

Обидва вони записують двійковий підпис на стандартний вихід. dgst бере -hexопцію, надрукує текстове подання з деякими подробицями про форму підпису. pkeyutl приймає -hexdumpваріант, який є менш корисним. Обидва приймуть і ключі RSA, і DSA. Я поняття не маю, який формат виводу. Дві команди створюють різні формати. У мене складається враження, що pkeyutl вважається більш сучасним, ніж dgst .

Щоб перевірити ці підписи:

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

і:

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

Проблема тут є $PUBLIC_KEY_FILE. OpenSSL не може читати формат відкритого ключа OpenSSH, тому його не можна просто використовувати id_rsa.pub. У вас є кілька варіантів, жоден ідеал.

Якщо у вас є версія OpenSSH 5.6 або новішої версії, ви, очевидно, можете це зробити:

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

Який запише відкритий ключ на стандартний вихід у форматі PEM, який OpenSSL може прочитати.

Якщо у вас є приватний ключ, і це ключ RSA, тоді ви можете витягнути з нього відкритий ключ (я припускаю, що закодований PEM файл приватного ключа включає копію відкритого ключа, оскільки не можна отримати відкритий ключ від приватного ключа) і скористайтеся цим:

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

Я не знаю, чи є еквівалент DSA. Зауважте, що такий підхід вимагає певної співпраці з власником приватного ключа, який повинен буде витягнути відкритий ключ та надіслати його до потенційного верифікатора.

Нарешті, ви можете використовувати програму Python, написану розділом під назвою Lars, для перетворення відкритого ключа з формату OpenSSH у формат OpenSSL.


1
Я хотів би лише зазначити, що "не можна отримати відкритий ключ із самого приватного ключа", це неправда. На практиці (тобто, у всіх криптосистемах, які фактично використовуються) публічний ключ легко виводиться з приватного ключа більшу частину часу.
kirelagin

@kirelagin: Я цього не знав. Не могли б ви сказати мені чи зв’язати мене з додатковою інформацією про те, як це можна зробити?
Том Андерсон

1
Я не впевнений, чи є якісь особливі читання на цю тему ... Давайте подумаємо над цим. Візьміть будь-яку дискретну криптосистему на основі журналу (ElGamal). У цьому випадку приватний ключ є (розмір групи, генератор, потужність), а відкритий ключ - (розмір групи, генератор, генератор ^ потужність). Отже, увійти складно, але потужності немає, ви просто обчислите його.
kirelagin

У випадку RSA ця інверсія насправді складна, але тут ситуація дещо інша. Відкритим ключем є (n, d), а приватний ключ - (n, d ^ (- 1) mod phi (n)). Інвертувати d також буде складно, якби ви не зберігали phi (n), але ось хитрість: майже кожен використовує e = 65537 (коли ви створюєте ключ, є можливість змінити цей замовчування, але я ніколи не бачив будь-хто, хто його використовує, оскільки це не має жодного практичного сенсу), тому отримання відкритого ключа з приватного є тривіальним.
kirelagin

З кривими Еліптик це фактично те саме, що і з дискретним журналом і потужністю, інвертування легко. Однак, я не впевнений в інших криптосистемах, але ці три - це ті, які використовуються на практиці.
kirelagin

10

@ Відповідь Тома допомогла мені почати роботу, але нічого не вийшло.

Ці команди працюватимуть із:

  • OpenSSL 1.0.1 14 березня 2012 року
  • OpenSSH_5.9p1

Використання 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

Використання 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

Версія pkeyutl може підписувати лише файли невеликого розміру. Хоча dgst може підписувати довільно великі файли, тому що він потребує дайджесту, перш ніж підписувати результат.


Мені також відповідь Stephen.z була відпрацьована. Спочатку я деякий час грав у відповідь Тома і, нарешті, знайшов відповідь Stephen.z, яка мені добре працює. Дякую Stephen.z!
Grzegorz Wierzowiecki

PS Тут я поділився своїми фрагментами: gist.github.com/gwpl/2c7636f0b200cbfbe82cc9d4f6338585
Grzegorz Wierzowiecki

Ви намагалися використовувати pkeyutl, щоб підписати лише хеш файлу?
Гая

-3

Щоб перевірити ці підписи - простіше рішення:

Найпростіший спосіб переконатися в тому, що підписаний документ є однаковим - це повторно генерувати файл цифрового підпису, а потім використовувати diff, щоб перевірити, чи два файли підписів однакові.


3
Ви думаєте про хеші , а не про підписи . Аналогічно, але не те саме: хеш лише підтверджує, що файл не змінився; підпис також підтверджує, звідки він прийшов.
Пісквор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.