Как перезаписать/обновить зашифрованный столбец с помощью SQLAlchemy при потере ключа шифрования?

#python #flask #encryption #sqlalchemy

Вопрос:

Я использую SQLAlchemy с SQLite в приложении Flask. У меня есть модель под названием User:

 class User(UserMixin,db.Model):
    id = db.Column(db.Integer, primary_key=True)  
    email = db.Column(db.String(100), unique=True) 
    otp_secret  = db.Column(EncryptedType( db.Unicode, get_user_personal_key))
    ...
 

Я использовал encryptedType для шифрования столбца пользователя модели под названием otp_secret, используя динамический ключ, сгенерированный из хэша пароля пользователя. Когда пользователь входит в систему, ключ генерируется и сохраняется в сеансе. Затем SQLAlchemy использует ключ из сеанса, возвращенный функцией обратного вызова get_user_personal_key (), для расшифровки столбца otp_secret.

Если пользователь хочет изменить пароль, я делаю следующее:

  • Сгенерируйте ключ шифрования/дешифрования из старого пароля и сохраните его в сеансе,
  • Запросите данные пользователя из базы данных, чтобы SQLAlchemy использовал ключ из сеанса для расшифровки otp_secret
  • Создайте новый ключ шифрования/дешифрования из нового пароля и перезапишите старый ключ в сеансе.
  • Сохраните UserX в базе данных, чтобы SQLAlchemy использовала новый ключ шифрования для шифрования столбца otp_secret

До сих пор все работало нормально, но что, если пользователь потерял свой пароль? Пожалуйста, как я могу перезаписать старый otp_secret, не имея старого ключа шифрования, если это возможно?

Комментарии:

1. Смысл шифрования в том, чтобы кто-то без ключа не смог прочитать/обработать/любую зашифрованную информацию, поэтому, если вы потеряли ключ, я думаю, что вы застряли.

2. Вы правы, и я не хочу расшифровывать старый otp_secret, а создаю новое значение и обновляю им таблицу пользователей.

3. Итак, вы хотите полностью заменить старое значение?

4. Вам нужен обходной путь, а не что-то очень простое. Если пользователь потерял свой пароль, вам нужен механизм, позволяющий ему установить новый пароль, основываясь на том, что он является фактическим пользователем. Простым примером может быть сброс пароля по электронной почте. Вы доверяете электронной почте пользователя, вы отправляете новый ключ на его электронную почту или любой другой механизм, с помощью которого вы хотите, чтобы он установил новый пароль.

5. Да, я хочу полностью заменить старое значение. Я отправляю код подтверждения по электронной почте. Проблема в том, что я не могу перезаписать старое значение с помощью SQLAlchemy без старого ключа шифрования. Чтобы обновить элемент пользователя, я должен сначала получить этого пользователя из примера базы данных : UserX = User.query.filter_by(электронная почта=»<адрес@some_email>»).сначала() только после этого я могу установить новое значение otp_secret следующим образом : UserX,otp_secret = gen_otp_sec(). Есть ли способ записи в БД без чтения или, по крайней мере, без расшифровки столбца?

Ответ №1:

Вы можете изменить базу данных с помощью sql-запроса.

 UPDATE table_name SET column1 = value1, column2 = value2 ... WHERE column_name = something
 

Комментарии:

1. Спасибо, я попробую это сделать.

2. @Ахмед эта WHERE деталь необязательна.