Ключи и подписи: приватный и публичный ключ

Приватный ключ — это право подписи, публичный — способ её проверить. Один секрет, который нельзя показывать никому.

«Подпись доказывает, что ты владеешь секретом, не раскрывая сам секрет. В этом вся магия криптографии с открытым ключом.»

Если баланс лежит в общем реестре, что мешает любому отправить мои монеты? Ответ — цифровая подпись. Она доказывает, что транзакцию создал именно владелец адреса, и никто другой. В основе — асимметричная криптография, то есть пара связанных ключей.

Два ключа — одна пара

  • Приватный ключ — твой главный секрет. Им ты подписываешь транзакции. Его нельзя показывать никому и никогда.
  • Публичный ключ (и производный от него адрес) — его можно публиковать. По нему другие проверяют твою подпись и присылают тебе монеты.

Ключи связаны односторонней математикой: публичный легко получить из приватного, но обратно — никак. Это как замок и ключ: по виду замка не изготовить ключ.

Как работает под капотом

Когда ты отправляешь монеты, кошелёк берёт данные транзакции и приватный ключ и создаёт подпись. Сеть проверяет подпись твоим публичным ключом. Если подпись сходится — транзакция настоящая. Подменить данные нельзя: изменишь хоть символ, и подпись перестанет сходиться.

        Подпись и проверка

   ПОДПИСАНТ (владелец):
     данные tx + приватный ключ  -->  подпись

   СЕТЬ (проверяющий):
     данные tx + публичный ключ + подпись  -->  верно/неверно

   Приватный ключ НИКОГДА не покидает кошелёк.

Покажем идею подписи на упрощённой модели (настоящие подписи используют эллиптические кривые, но принцип «секрет доказывает авторство» тот же).

Попробуй сам ▶ Запусти код прямо здесь — он работает в браузере:

import hashlib

# УПРОЩЁННАЯ модель для понимания идеи (НЕ настоящая криптография!)
private_key = 'мой-тайный-ключ-12345'

def public_key(priv):
    # односторонняя функция: из приватного получаем публичный
    return hashlib.sha256(priv.encode()).hexdigest()

def sign(message, priv):
    return hashlib.sha256((priv + '|' + message).encode()).hexdigest()

def verify(message, signature, priv):
    # в реальности проверяют публичным ключом без знания приватного
    return sign(message, priv) == signature

pub = public_key(private_key)
tx = 'Аня -> Боря: 5 монет'
sig = sign(tx, private_key)

print('Публичный ключ (адрес):', pub[:16], '...')
print('Подпись валидна?       ', verify(tx, sig, private_key))

# Подменим транзакцию -> подпись больше не сходится
fake = 'Аня -> Боря: 500 монет'
print('Подделка проходит?     ', verify(fake, sig, private_key))

Частые заблуждения

  • «Публичный ключ нужно прятать». Наоборот, его публикуют — он для приёма средств и проверки подписи.
  • «Подпись — это пароль». Нет: для каждой транзакции подпись своя, и она привязана к её данным.
  • «По адресу можно вычислить приватный ключ». Нельзя: это вычислительно невозможно при правильной криптографии.

Важно понимать (риски)

Вся безопасность сводится к одному: кто владеет приватным ключом, тот владеет средствами. Узнал злоумышленник твой ключ — деньги ушли безвозвратно, отменить нельзя. Поэтому приватный ключ нельзя вводить на сомнительных сайтах, фотографировать, хранить в облаке или в переписке. Любой, кто просит твой приватный ключ или сид-фразу под любым предлогом, — мошенник. Запомни это как аксиому.

Разбор: почему адрес — это «сокращённый» публичный ключ

Ты мог заметить, что адрес кошелька и публичный ключ — вроде бы похожие, но не одинаковые вещи. Разберём связь. Из приватного ключа математически выводится публичный ключ. А из публичного ключа, прогнав его через хеш-функцию и немного укоротив, получают адрес — ту самую строку, на которую тебе присылают монеты. То есть адрес — это «отпечаток» публичного ключа, более короткий и удобный.

Зачем лишний шаг? Во-первых, адрес короче и его проще передавать. Во-вторых, это дополнительный слой защиты: пока ты не потратишь монеты, сеть видит только адрес, а не сам публичный ключ, что усложняет некоторые теоретические атаки. Получается красивая лесенка: приватный ключ рождает публичный, публичный — адрес, и каждый шаг односторонний. Двигаться по ней можно только вниз: зная адрес, нельзя подняться обратно к публичному ключу, а уж тем более к приватному.

Итоги

  • Пара ключей: приватный (секрет для подписи) и публичный (для проверки и приёма).
  • Подпись доказывает авторство транзакции без раскрытия секрета.
  • Публичный ключ выводится из приватного, но не наоборот.
  • Кто владеет приватным ключом — владеет средствами; его нельзя раскрывать никому.
Проверьте себя
1. Какой ключ можно безопасно публиковать?
AПриватный ключ
BПубличный ключ (адрес)
CСид-фразу
DОба ключа
2. Что доказывает цифровая подпись транзакции?
AЧто у отправителя много денег
BЧто транзакцию создал владелец приватного ключа и данные не изменены
CЧто комиссия оплачена
DЧто блок намайнен