“За plain-text руки оторву” или правильно храним персональные данные пользователей

Давайте на секундочку перенесемся в наше детство. Надеюсь, все помнят “секретики” – маленькие тайнички, в которых мы оставляли всякие важные нам мелочи, которые мы хотели показывать только нашим близким друзьям. Мы взрослели, времена успели измениться, мы стали программистами и…снова встретили те самые “секретики”, правда, если ты их не сохранишь должным образом, всё может пойти наперекосяк.

Но телеграфирует, как обычно, Corvych, желая Вам приятного дня и чтения. Сегодня наша тема для разговора – шифрование данных для надежного их хранения. Понеслась!

Начнем с того, что в нашем чудесном мире имеется куча разных алгоритмов шифрования данных, но самые популярные на сегодняшний день являются MD5, SHA и RSA

Сегодня рассмотрим два из них – MD5 и RSA

Как Вы уже могли понять, я взял именно их не просто так. Они вообще не похожи друг на друга.

Начнем с того, что MD5 шифрует (или хэширует) данные, но не расшифровывает. Он может быть полезен только для работы с паролями на каком-нибудь сайтике, так как мы записываем пароль пользователя куда-нибудь в базу данных в хэшированном виде, а проверка правильности ввода пароля происходит сравнением двух хэшей – пароля из базы данных и пароля, введенного пользователем.

Для примера приведу код на Python:

import hashlib # Импортируем библиотеку hashlib, она идет по стандарту
password = "SUPER_SLOZHNIY_PAROL_NIKTO_NE_VZLOMAET!!!" # Это наш пароль
hashed_password = hashlib.md5(password.encode('utf-8')).hexdigest() # Хэшируем пароль алгоритмом MD5
print(hashed_password) # Выведем его в консоль

Данный код хэширует строку (наш пароль) и выводит её. Переменную hashed_password можно смело запихивать в базу данных.

Теперь напишем функцию на проверку пароля:

def check_password(hashed_password, password):
    pass_hash = hashlib.md5(password.encode('utf-8')).hexdigest() # Хэшируем пароль, введенный пользователем
    if pass_hash == hashed_password: # Проверим совпадение хэшей
        return True
    else:
        return False

Эта функция принимает на вход хэшированный пароль (например, из базы данных) и пароль пользователя, второй хэширует и проверяет схожесть хэшей, возвращая True или False в зависимости от ситуации.

Но наступает время, когда надо не только шифровать, но и расшифровывать. И тут MD5 сдаёт позиции, так как не умеет расшифровывать…

Переходим к RSA и рассмотрим, что он умеет.

Тут уже всё куда слаще – шифруем и расшифровываем. Для этого используются ключи (приватный и публичный) – файлы, зачастую в расширении .pem

Давайте покажу наглядно, надо решить задачку: Игорь хочет передать сообщение своей любовнице, но только так, чтобы его жена не смогла по пути прочитать.

Он неведомым нам образом просит любовницу купить шкатулку с замком (публичным ключом), отдать ему, а ключ от замка оставить себе (приватный ключ).

Алгоритм таков: Игорь пишет сообщение, кладет листочек в шкатулку, шифруя его замком, а любовница её получает и расшифровывает его ключом от замка.

Теперь вернемся в IT мир. Любовница поднимает сервер базы данных, генерирует ключи, публичный ключ отправляет Игорю, ждет его сообщение и расшифровывает его.

Поможем им тоже с помощью Python:

import rsa # Сначала её надо установить pip install rsa

# Действия любовницы
def prepare_keys(): # Генерим ключи
    publicKey, privateKey = rsa.newkeys(512)
    
    pub_f = open('public.pem', 'wb') # Создадим файл публичного ключа
    priv_f = open('private.pem', 'wb') # Создадим файл приватного ключа

    pub_f.write(publickey.save_pkcs1("PEM")) # Запишем ключи
    priv_f.write(privatekey.save_pkcs1("PEM"))

    pub_f.close()
    priv_f.close()

prepare_keys()

# Действия Игоря
def encrypt_message(message): # Шифруем маляву
    with open('public.pem', mode='rb') as publicfile: # Откроем файл ключа
        pubkeydata = publicfile.read()

    publicKey = rsa.PublicKey.load_pkcs1(pubkeydata) # Запишем ключик для дальнейшего использования
    encrypted_message = rsa.encrypt(message, publicKey) # Шифруем
    return encrypted_message # Возвращенное отправляем любовнице

message_to_lover = encrypt_message("Давай сегодня встретимся в кафе на Невском в 8?")

# Действия Любовницы

def decrypt_message(message): # Расшифровываем сообщение
    with open('private.pem', mode='rb') as privatefile:
        privkeydata = privatefile.read()

    privateKey = rsa.PrivateKey.load_pkcs1(privkeydata)

    decrypted_message = rsa.decrypt(message, privateKey).decode() # Расшифровываем
    return decrypted_message # Возвращенное значение можно читать

message_from_igor = decrypt_message(message_to_lover) # Вот и сообщение от Игоря

Игорь смог успешно скрыть сообщение от своей жены и отправить его любовнице, а вот как он в 8 сбежит из дома – это уже не наш вопрос😊

Подведем итог. Мы научились шифровать любые данные, а также расшифровывать в случае с RSA.

Огромное спасибо за уделенное время! Не прощаемся)