← Назад к вопросам
В чем разница между хешированием и шифрованием?
2.2 Middle🔥 121 комментариев
#Безопасность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Хеширование vs Шифрование
Оба способа преобразуют данные, но преследуют совершенно разные цели. Это критичное различие для безопасности.
Хеширование (Hashing) — односторонее преобразование
Хеширование преобразует данные в фиксированную строку так, что нельзя вернуть исходные данные.
import hashlib
password = "mypassword123"
hash_result = hashlib.sha256(password.encode()).hexdigest()
print(hash_result) # a1b2c3d4e5f6...
# Нельзя получить исходный пароль обратно!
Характеристики хеша:
- Один вход = один выход
- Изменение одного символа меняет хеш полностью
- Быстро вычисляется
- Фиксированный размер выхода
- Невозможно инвертировать
import hashlib
text1 = "hello"
text2 = "hallo"
hash1 = hashlib.sha256(text1.encode()).hexdigest()
hash2 = hashlib.sha256(text2.encode()).hexdigest()
print(f"Hash1: {hash1}")
print(f"Hash2: {hash2}")
# Хеши полностью разные!
Шифрование (Encryption) — двустороннее преобразование
Шифрование преобразует данные так, что можно вернуть исходные данные, если знаешь ключ.
from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher = Fernet(key)
plaintext = "my secret message"
ciphertext = cipher.encrypt(plaintext.encode())
print(f"Зашифровано: {ciphertext}")
decrypted = cipher.decrypt(ciphertext)
print(f"Расшифровано: {decrypted.decode()}")
Характеристики шифрования:
- Требует ключ для расшифровки
- Шифрование и расшифровка
- Обычно медленнее хеширования
- Размер может быть больше исходных данных
- Можно инвертировать (если знаешь ключ)
Сравнительная таблица
| Аспект | Хеширование | Шифрование |
|---|---|---|
| Направление | Одностороннее | Двустороннее |
| Обратимость | Нет | Да (с ключом) |
| Ключ | Не нужен | Обязателен |
| Размер вывода | Фиксированный | Переменный |
| Скорость | Быстро | Медленнее |
| Область применения | Пароли, контрольные суммы | Приватные данные |
| Цель | Проверка целостности | Конфиденциальность |
Практические примеры
Хеширование паролей
import hashlib
class UserAuthenticator:
@staticmethod
def hash_password(password):
return hashlib.sha256(password.encode()).hexdigest()
@staticmethod
def verify_password(password, hash_stored):
return hashlib.sha256(password.encode()).hexdigest() == hash_stored
user_password = "mypassword123"
stored_hash = UserAuthenticator.hash_password(user_password)
login_password = "mypassword123"
is_valid = UserAuthenticator.verify_password(login_password, stored_hash)
print(f"Пароль верен: {is_valid}")
Лучше с bcrypt:
import bcrypt
password = "mypassword123"
salt = bcrypt.gensalt()
hashed = bcrypt.hashpw(password.encode(), salt)
login_password = "mypassword123"
is_valid = bcrypt.checkpw(login_password.encode(), hashed)
print(f"Пароль верен: {is_valid}")
Шифрование чувствительных данных
from cryptography.fernet import Fernet
class DataEncryptor:
def __init__(self):
self.key = Fernet.generate_key()
self.cipher = Fernet(self.key)
def encrypt_data(self, data):
encrypted = self.cipher.encrypt(data.encode())
return encrypted
def decrypt_data(self, encrypted_data):
decrypted = self.cipher.decrypt(encrypted_data)
return decrypted.decode()
encryptor = DataEncryptor()
card_number = "4532-1234-5678-9999"
encrypted_card = encryptor.encrypt_data(card_number)
print(f"Зашифровано: {encrypted_card}")
decrypted_card = encryptor.decrypt_data(encrypted_card)
print(f"Расшифровано: {decrypted_card}")
Хеширование для контрольных сумм
import hashlib
class FileIntegrityChecker:
@staticmethod
def calculate_hash(filename):
sha256_hash = hashlib.sha256()
with open(filename, "rb") as f:
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
@staticmethod
def verify_file(filename, expected_hash):
actual_hash = FileIntegrityChecker.calculate_hash(filename)
return actual_hash == expected_hash
file_hash = FileIntegrityChecker.calculate_hash("data.txt")
print(f"Хеш файла: {file_hash}")
is_intact = FileIntegrityChecker.verify_file("data.txt", file_hash)
print(f"Файл не изменился: {is_intact}")
Когда использовать что
Хеширование:
- Хранение паролей в БД (bcrypt, argon2)
- Проверка целостности данных
- Кэширование (хеш как ключ)
- Проверка дублей в больших наборах данных
Шифрование:
- Передача приватных данных по сети (HTTPS)
- Хранение конфиденциальной информации
- Защита от несанкционированного доступа
- Резервные копии с паролем
Частые ошибки
Ошибка 1: Использование простого хеша для паролей
# ПЛОХО!
import hashlib
password_hash = hashlib.sha256(password.encode()).hexdigest()
# Нет соли, слишком быстро, легко подобрать
Хорошо: используй bcrypt
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
# Медленно, с солью, адаптивно
Ошибка 2: Передача незашифрованных приватных данных
# ПЛОХО!
sensitive_data = "credit-card-4532-1234-5678-9999"
send_to_api(sensitive_data) # Незащищённо!
# Хорошо:
encrypted = cipher.encrypt(sensitive_data.encode())
send_to_api(encrypted) # По HTTPS с шифрованием
Итоговое правило
- Хеширование — когда нужна проверка (пароли, контрольные суммы)
- Шифрование — когда нужна конфиденциальность (карты, личные данные)