Опубліковано: · Оновлено: · автор: kodewright
Як безпечно згенерувати SSH-ключ: інструкція 2026
Як створити SSH-ключ через ssh-keygen: ed25519 чи RSA, що дають парольна фраза й раунди KDF, якщо файл ключа вкрадуть, ssh-agent і відкликання доступу.

Щоб безпечно згенерувати SSH-ключ у 2026 році, достатньо однієї команди і справжньої парольної фрази, коли програма її попросить:
ssh-keygen -t ed25519 -a 64 -C "you@laptop-2026"
-t ed25519 задає тип ключа, -a 64 — скільки раундів bcrypt захищатимуть файл приватного ключа на диску, а -C — це мітка, яка потрапить в authorized_keys на сервері, щоб згодом ключі можна було розрізнити. Сама команда — найпростіша частина. Чи перетвориться загублений ноутбук або злита резервна копія на доступ до ваших серверів, вирішують парольна фраза, те, як ви завантажуєте ключ в агент, і те, наскільки швидко ви можете прибрати ключ із серверів, коли він стає непотрібним.
Що робить кожен прапорець ssh-keygen
| Прапорець | Призначення | Примітки |
|---|---|---|
-t ed25519 | Тип ключа | За замовчуванням з OpenSSH 9.5 (жовтень 2023). Я все одно пишу його явно в документації та скриптах, щоб старіша машина мовчки не створила щось інше |
-a 64 | Раунди KDF | Скільки раундів bcrypt_pbkdf перетворюють парольну фразу на ключ, яким шифрується файл. Старіші версії мали за замовчуванням 16; OpenSSH 10.6 (жовтень 2026) підняв значення до 32 |
-C "you@laptop-2026" | Коментар | Довільний текст у кінці рядка відкритого ключа. Вказуйте людину й пристрій, а не лише email |
-f ~/.ssh/id_ed25519_work | Ім'я файлу | Потрібне, лише якщо ви тримаєте окремі ключі для різних задач |
Реальний запуск, скорочено (блок randomart прибрано):
$ ssh-keygen -t ed25519 -a 64 -C "you@laptop-2026"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/you/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/you/.ssh/id_ed25519
Your public key has been saved in /home/you/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:IikmcGblWuCYS6a6eqQ24RzSyqc9o36qkoPLnzdOxLE you@laptop-2026
На виході два файли. id_ed25519 — приватний ключ, він ніколи не залишає машину. id_ed25519.pub — один рядок, який ви вставляєте в GitHub або копіюєте на сервери.
Ed25519 чи RSA у 2026 році
Для нового ключа — ed25519. Відкритий ключ займає 68 символів base64, підпис швидкий, а nonce для підпису виводиться з ключа й повідомлення (RFC 8032), а не береться з генератора випадкових чисел. Останнє важить більше за розмір: ECDSA потребує свіжого секретного випадкового числа для кожного підпису, і якщо воно повториться, приватний ключ витікає. Саме так у 2010 році відновили ключ, яким Sony підписувала ПЗ для PS3.
| Тип ключа | Відкритий ключ (символів base64) | Рівень стійкості | Статус в OpenSSH |
|---|---|---|---|
| ed25519 | 68 | ~128 біт | За замовчуванням з 9.5 |
| RSA 3072 | 544 | 128 біт (NIST SP 800-57) | Розмір за замовчуванням, якщо обрати RSA |
| RSA 2048 | 372 | 112 біт | Досі приймається, для нових ключів замалий |
| ECDSA P-256 | 140 | 128 біт | Працює; залежить від якісного nonce для кожного підпису |
| DSA | Повністю видалений в OpenSSH 10.0 (квітень 2025) |
Мої власні ключі — RSA, і вони досі працюють усюди, де мені потрібно. Фразу «OpenSSH 8.8 вимкнув ssh-rsa» (вересень 2021) іноді читають як «RSA-ключі мертві», але 8.8 вимкнув саме підписи RSA з SHA-1. Той самий RSA-ключ автоматично підписує через SHA-256 або SHA-512. Якщо у вас теж RSA-ключі, дві перевірки дадуть більше, ніж заміна ключів із принципу:
ssh-keygen -lf ~/.ssh/id_rsa.pub # перше число — розмір ключа: має бути 3072+
head -2 ~/.ssh/id_rsa # у якому форматі збережено приватний ключ
Якщо друга команда виводить -----BEGIN RSA PRIVATE KEY-----, а за ним Proc-Type: 4,ENCRYPTED, ключ збережено у старому форматі PEM від OpenSSL, який ssh-keygen використовував за замовчуванням до OpenSSH 7.8 (серпень 2018). Цей формат отримує ключ шифрування з парольної фрази одним проходом MD5, без жодного фактора складності. ssh-keygen -p -a 64 -f ~/.ssh/id_rsa перезапише файл як -----BEGIN OPENSSH PRIVATE KEY----- з bcrypt_pbkdf, а відкритий ключ не зміниться.
Є ще два варіанти. З апаратним FIDO2-ключем ssh-keygen -t ed25519-sk (OpenSSH 8.2+) тримає приватний ключ на пристрої, а файл у ~/.ssh — лише дескриптор, марний без токена й дотику до нього. У release notes самого OpenSSH сказано, що Ed25519 токени підтримують рідше, ніж ECDSA, тож запасний варіант — -t ecdsa-sk. Гібридний постквантовий тип mldsa44-ed25519 увімкнули в OpenSSH 10.6, але сервери на старіших версіях його не приймуть, тому я поки не робив би його чиїмось єдиним ключем.
Що дає парольна фраза, коли файл ключа витік
Парольна фраза має значення лише в одному сценарії, і він найпоширеніший: у когось опинилася копія id_ed25519. Вкрадений ноутбук, домашня тека в резервній копії, репозиторій із dotfiles, який захопив ~/.ssh, шкідлива програма, що читає файли. Відтак перебір іде офлайн, без обмеження швидкості й без жодного запису в логах на вашому боці.
OpenSSH шифрує приватний ключ алгоритмом AES-256-CTR, а ключ AES отримує з парольної фрази через bcrypt_pbkdf. Кожен раунд KDF виконує bcrypt-подібну підготовку ключа з 64 проходами розширення, що приблизно дорівнює одному хешу bcrypt з cost 6, а 48 байтам ключа AES і IV потрібні два вихідні блоки. За 32 раундів це близько 64 хешів bcrypt з cost 6 на одну спробу. Якщо масштабувати виміряну hashcat швидкість bcrypt на RTX 4090 (184 000 на секунду при cost 5), виходить приблизно 1 440 спроб на секунду, стільки ж, скільки в bcrypt з cost 12. Це моя оцінка з алгоритму, а не опублікований бенчмарк саме цього формату файлу, тож сприймайте таблицю як порядок величин.
H = W × log₂(7776) ≈ W × 12.9 bits W = random words from the EFF list
average time = 7776^W / 2 / guesses per second
Тут H — ентропія в бітах, W — кількість випадкових слів зі списку EFF, а середній час — це половина простору варіантів, поділена на швидкість перебору.
| Парольна фраза | Ентропія | Середній час, одна RTX 4090, 32 раунди |
|---|---|---|
| Немає | 0 біт | Перебирати нічого: файлом можна користуватися як є |
| Слово плюс рік, які ви обрали самі | Низька | Падає під перебором за словником із правилами; вважайте, що фрази немає |
| 2 випадкові слова EFF | 25,8 біта | ~6 годин |
| 3 випадкові слова EFF | 38,8 біта | ~5 років |
| 4 випадкові слова EFF | 51,7 біта | ~40 000 років |
| 5 випадкових слів EFF | 64,6 біта | ~310 млн років |
| 8 випадкових друкованих символів ASCII | 52,6 біта | ~73 000 років |
Підлаштуйте під свою ситуацію: ключ, збережений зі старим значенням у 16 раундів, ламається вдвічі швидше, ферма з 8 GPU ділить кожен рядок на 8 (чотири слова — приблизно 5 000 років), а -a 64 подвоює кожен рядок. Ці цифри справедливі лише для слів, обраних випадково. Фраза, яку ви вигадали самі, належить до другого рядка.
Я вважав би чотири випадкові слова мінімумом, а для ключів, що мають доступ до продакшену, брав би п'ять. Збільшення -a у стільки ж разів сповільнює й розшифрування для вас, але з агентом ви платите цю ціну раз за сесію, тож перехід із 32 на 64 раунди майже нічого не коштує.
Не вигадуйте слова самі. Режим парольної фрази в моєму Генераторі паролів обирає їх через crypto.getRandomValues() і показує ентропію в бітах, поки ви змінюєте кількість слів; він працює у вашому браузері й нікуди нічого не надсилає. Для таблиці вище це принципово: у генератора на основі Math.random() внутрішній стан можна відновити з кількох значень, і тоді «випадкові» слова такими не є. Щоб порівняти фразу, якою ви вже користуєтеся, введіть у Перевірку стійкості пароля фразу такої самої форми (стільки ж слів того ж типу, але не справжню). Чим відрізняються секрети зі слів і з символів, я розбирав у статті парольна фраза чи пароль.
ssh-agent: вводити парольну фразу раз за сесію
Якщо парольну фразу треба вводити при кожному підключенні, рано чи пізно хтось її з ключа зніме. Агент тримає розшифрований ключ у пам'яті й підписує замість вас:
eval "$(ssh-agent -s)"
ssh-add -t 8h ~/.ssh/id_ed25519 # забути ключ через 8 годин
ssh-add -l # що зараз тримає агент
На macOS ssh-add --apple-use-keychain ~/.ssh/id_ed25519 зберігає парольну фразу в Keychain, а AddKeysToAgent yes разом із UseKeychain yes у секції Host * файлу ~/.ssh/config завантажують ключ при першому використанні.
Обережно з пересиланням агента (ForwardAgent yes або ssh -A). Поки ви підключені, будь-хто з root-доступом на віддаленій машині може скористатися вашим пересланим агентом і підписуватися вашим ключем на інших серверах. Щоб дістатися машин за bastion-хостом, ssh -J bastion target (ProxyJump) доведе вас туди, не відкриваючи агента.
Покладіть відкритий ключ на сервер, потім вимкніть паролі
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
Команда додає рядок із вашого .pub до ~/.ssh/authorized_keys на сервері. Під час входу мережею не передається нічого секретного: після обміну ключами клієнт підписує приватним ключем блок даних з ідентифікатором сесії, а сервер перевіряє цей підпис відкритим ключем, який у нього записаний (RFC 4252, розділ 7). Підпис прив'язаний до однієї сесії, тож записаний вхід не вийде відтворити повторно.
client server
| key exchange -> session identifier H |
| "publickey" request + signature over H |
| (made with the private key) ------------> |
| | verify with the key in
| | ~/.ssh/authorized_keys
| <------------------------- success / fail |
Коли вхід за ключем працює, вимкніть паролі в /etc/ssh/sshd_config:
PasswordAuthentication no
KbdInteractiveAuthentication no
Перш ніж перезавантажувати sshd, перевірте, які налаштування він реально застосує, бо файли в /etc/ssh/sshd_config.d/ можуть перекривати основний файл (хмарні образи Ubuntu постачаються з 50-cloud-init.conf, де може стояти PasswordAuthentication yes):
sudo sshd -t && sudo sshd -T | grep -iE 'passwordauth|kbdinteractive'
Не закривайте поточну сесію і перевірте новий вхід із другого термінала, перш ніж щось закривати. Так у вас лишиться шлях назад, якщо конфігурація виявиться хибною.
Права доступу та відбитки ключів
OpenSSH відмовляється працювати з приватним ключем, який можуть читати інші користувачі, тож налаштуйте права один раз:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/id_ed25519.pub
ssh-keygen -lf ~/.ssh/id_ed25519.pub виводить відбиток: 256 SHA256:IikmcG… you@laptop-2026 (ED25519). Захищає вас інший відбиток — відбиток ключа хоста, який ви бачите при першому підключенні до нового сервера. Порівняйте його зі значенням у консолі провайдера або з виводом ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub на самому сервері, а не вводьте «yes» за звичкою.
Відбиток — це SHA-256 від декодованого блоку ключа, закодований у base64 без кінцевого =. Якщо хочете переконатися самі, декодуйте середнє поле рядка .pub у файл через Base64 декодувальник, захешуйте цей файл у Генераторі хешів з виводом у base64, і результат збіжиться з тим, що показує ssh-keygen.
Ротація й відкликання доступу відбуваються на сервері
Приватний ключ не можна відкликати з боку клієнта. Він перестає працювати лише тоді, коли зникає кожен рядок authorized_keys, що йому довіряє. Коли мені доводилося мати справу з людьми, які йшли з команди, робота була саме такою: пройтися серверами й оновити, хто має доступ. Кілька звичок роблять цю роботу короткою:
- Один ключ на людину на пристрій. Тоді загублений ноутбук означає видалити один рядок, і більше нікому нічого не треба ротувати.
- Коментарі, з яких видно людину й машину (
-C "anna@work-laptop-2026"), щобgrep anna ~/.ssh/authorized_keysна всіх хостах знаходив кожен рядок. - Ключі для CI і скриптів деплою обмежені на боці сервера, наприклад
from="203.0.113.10",restrict,command="/usr/local/bin/deploy"перед ключем, замість парольної фрази, яку о третій ночі ніхто не введе. - Коли серверів більше кількох, сертифікати SSH: підписуйте ключі користувачів ключем CA (
ssh-keygen -s ca_key -I anna -n deploy -V +30d id_ed25519.pub) і дозвольте їм спливати, замість вишукувати рядки вручну.
Ніколи не комітьте приватний ключ і не пускайте ~/.ssh у репозиторії з dotfiles та теки, що синхронізуються з хмарою. Якщо ключ таки витік, поводьтеся з ним як з будь-якими викраденими обліковими даними: спершу приберіть його із серверів, потім генеруйте заміну.
Якщо після цієї статті зробити лише одне, виконайте head -1 для кожного приватного ключа в ~/.ssh. Усе без парольної фрази або досі у старому форматі PEM сьогодні ж отримує ssh-keygen -p -a 64 -f <file>.
FAQ
Яка команда найкраща для генерації SSH-ключа у 2026 році?
ssh-keygen -t ed25519 -a 64 -C "you@laptop-2026", а потім парольна фраза з чотирьох-п'яти випадкових слів. В OpenSSH 9.5 і новіших -t ed25519 і так стоїть за замовчуванням, але явно вказаний прапорець нічого не коштує і захищає вас на старіших системах.
Що обрати для SSH: ed25519 чи RSA?
Ed25519 для всього нового. RSA-ключі від 3072 біт досі нормальні й працюють після OpenSSH 8.8, який вимкнув лише підписи з SHA-1. Нові ключі RSA-2048 не генеруйте: 112 біт стійкості — найнижчий рівень, який NIST ще приймає.
Чи потрібна SSH-ключу парольна фраза?
Для будь-якого ключа, яким користується людина, так. Без неї скопійований файл — це готовий вхід. Чотири випадкові слова EFF за поточних стандартних 32 раундів, за моєю оцінкою, дають у середньому близько 40 000 років перебору на одній RTX 4090, а фраза, яку ви вигадали самі, падає під перебором за словником. Для ключів CI натомість обмежте на сервері, що ключ може робити.
Як додати парольну фразу до наявного SSH-ключа?
ssh-keygen -p -f ~/.ssh/id_ed25519. Команда спитає стару парольну фразу (просто натисніть Enter, якщо її не було) і перешифрує той самий ключ, тож на серверах нічого не зміниться. Додайте -a 64, щоб заодно збільшити кількість раундів KDF. Для старого ключа у форматі PEM команда також переведе файл у формат OpenSSH.
Де зберігаються SSH-ключі?
У ~/.ssh/: id_ed25519 (приватний, права 600) і id_ed25519.pub (відкритий). Резервну копію приватного ключа тримайте лише в зашифрованому місці, наприклад як вкладення в менеджері паролів або в зашифрованому образі диска. Відкритий ключ захисту не потребує.