← Назад к вопросам

Как происходит подпись?

2.7 Senior🔥 61 комментариев
#Безопасность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Как происходит подпись?

Подпись (цифровая подпись, Digital Signature) — это криптографический механизм для гарантии подлинности и неотказуемости данных. Это фундаментальный концепт в сетевой безопасности.

Принцип работы подписи

Цифровая подпись гарантирует:

  1. Аутентификацию — подтверждение, что данные созданы определённым отправителем
  2. Целостность — что данные не были изменены
  3. Неотказуемость — отправитель не может отрицать создание подписи

Асимметричное шифрование (RSA, ECDSA)

Основная схема

Используются две ключи:

  • Приватный ключ (private key) — секретный ключ, известный только владельцу
  • Публичный ключ (public key) — открытый ключ, доступный всем

Процесс подписания

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa, padding

# 1. Генерируем пару ключей
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
public_key = private_key.public_key()

# 2. Подписываем данные приватным ключом
message = b"Important document"
signature = private_key.sign(
    message,
    padding.PSS(
        mgf=padding.MGF1(hashes.SHA256()),
        salt_length=padding.PSS.MAX_LENGTH
    ),
    hashes.SHA256()
)

Процесс проверки подписи

# 3. Проверяем подпись публичным ключом
try:
    public_key.verify(
        signature,
        message,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256()
    )
    print("Подпись верна!")
except:
    print("Подпись некорректна!")

Хеширование перед подписью

На практике не подписывают данные целиком, а подписывают хеш:

from cryptography.hazmat.primitives import hashes

# Для больших файлов
with open("large_file.bin", "rb") as f:
    digest = hashes.Hash(hashes.SHA256())
    for chunk in iter(lambda: f.read(4096), b""):
        digest.update(chunk)
    file_hash = digest.finalize()

# Подписываем хеш
signature = private_key.sign(file_hash, ...)

JWT токены

В веб-приложениях используют JWT для подписи токенов:

import jwt
from datetime import datetime, timedelta

# Создание подписанного токена
payload = {
    "user_id": 123,
    "exp": datetime.utcnow() + timedelta(hours=1)
}

token = jwt.encode(
    payload,
    "secret_key",  # Приватный ключ (или секрет)
    algorithm="HS256"  # HMAC-SHA256
)

# Проверка подписи
try:
    decoded = jwt.decode(
        token,
        "secret_key",  # Тот же ключ
        algorithms=["HS256"]
    )
    print(f"User ID: {decoded['user_id']}")
except jwt.InvalidSignatureError:
    print("Токен поддельный!")

Электронная подпись (e-signature)

Для юридических документов используют квалифицированные сертификаты:

from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from datetime import datetime, timedelta

# Создание сертификата
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
subject = issuer = x509.Name([
    x509.NameAttribute(x509.oid.NameOID.COUNTRY_NAME, u"RU"),
    x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, u"John Doe"),
])

cert = (
    x509.CertificateBuilder()
    .subject_name(subject)
    .issuer_name(issuer)
    .public_key(private_key.public_key())
    .serial_number(x509.random_serial_number())
    .not_valid_before(datetime.utcnow())
    .not_valid_after(datetime.utcnow() + timedelta(days=365))
    .sign(private_key, hashes.SHA256())
)

HMAC (симметричная подпись)

Для симметричных ключей используют HMAC:

import hmac
import hashlib

# Подпись
secret = b"shared_secret_key"
message = b"Data to sign"
signature = hmac.new(
    secret,
    message,
    hashlib.sha256
).digest()

# Проверка
computed_signature = hmac.new(
    secret,
    message,
    hashlib.sha256
).digest()

if hmac.compare_digest(signature, computed_signature):
    print("Подпись верна")

Лучшие практики

  1. Никогда не делись приватным ключом — это основа безопасности
  2. Используй криптографически стойкие алгоритмы (SHA-256, не MD5)
  3. Храни приватные ключи безопасно (не в коде, использую HSM)
  4. Проверяй сертификаты на подлинность
  5. Используй известные библиотеки (cryptography, PyJWT), не пиши свои
  6. Регулярно ротируй ключи для долгосрочных систем

Заключение

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