Почему функция дешифрования меняет все значения на null?

Я пытаюсь зашифровать все данные компании. Но я буду видеть только нулевые значения, когда захочу их расшифровать. Я проверил свои данные после шифрования, и они выглядят зашифрованными.

Вот мой код

update TCB set Company=aes_encrypt(Company,'1234') WHERE Company= CONVERT(Company USING ASCII);
//I added where clause in case if there is any Encrypted data

select *,cast(aes_decrypt(Company,'1234') as char(100))  from TCB;

Заранее спасибо

1
0
142
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

AES_ENCRYPT() возвращает двоичные байты, а не текст. Когда вы сохранили зашифрованные данные в том же столбце, который, как я предполагаю, представляет собой столбец varchar или text с набором символов, он попытался интерпретировать двоичные байты как кодировки в наборе символов столбца. Вероятно, что многие байты не были допустимыми кодировками для этого набора символов, поэтому вы получили данные мусора, которые невозможно расшифровать.

mysql> create table tcb ( company text );

mysql> insert into tcb set company = 'company';

mysql> update tcb set company = aes_encrypt(company, '1234');
Query OK, 1 row affected, 1 warning (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 1

mysql> show warnings;
+---------+------+----------------------------------------------------------------------------------+
| Level   | Code | Message                                                                          |
+---------+------+----------------------------------------------------------------------------------+
| Warning | 1366 | Incorrect string value: '\x8F\x94O\x1D\xB9\x07...' for column 'company' at row 1 |
+---------+------+----------------------------------------------------------------------------------+

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

mysql> create table tcb (company text, company_enc blob);

mysql> insert into tcb set company = 'company';

mysql> update tcb set 
    company_enc = aes_encrypt(company, '1234'),
    company = NULL; /* no more plain text copy */

mysql> select aes_decrypt(company_enc, '1234') from tcb;
+----------------------------------+
| aes_decrypt(company_enc, '1234') |
+----------------------------------+
| company                          |
+----------------------------------+

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

mysql> update tcb set company = 'company';

mysql> update tcb set company = hex(aes_encrypt(company, '1234'));

mysql> select company from tcb;
+----------------------------------+
| company                          |
+----------------------------------+
| 8F944F1DB907685B94F8F21554E57396 |
+----------------------------------+

mysql> select aes_decrypt(unhex(company), '1234') from tcb;
+-------------------------------------+
| aes_decrypt(unhex(company), '1234') |
+-------------------------------------+
| company                             |
+-------------------------------------+

Билл Карвин, спасибо

user10184524 13.09.2018 22:23

Знаете ли вы, как предотвратить обновление, если ключевой пароль неверен?

user10184524 13.09.2018 22:50

Как AES_ENCRYPT() узнает, неверен ли ключевой пароль? Когда вы шифруете, любой ключ правильный. Когда вы расшифровка, вам нужно убедиться, что вы используете тот же ключ, который вы использовали при шифровании.

Bill Karwin 13.09.2018 23:03

Хорошо, отлично, и последний вопрос о шестнадцатеричном формате. Таким образом, это шифрование может происходить несколько раз, и я не хочу шифровать один файл несколько раз, я использовал WHERE Company = CONVERT (Company USING ASCII); чтобы убедиться, что данные еще не зашифрованы. Но теперь я использовал Hex и не знаю, как это проверить еще раз. у вас есть какие-нибудь рекомендации?

user10184524 13.09.2018 23:08

Рекомендую использовать две колонки. Один VARCHAR для хранения незашифрованной чистой строки, а другой VARBINARY, в котором вы храните только зашифрованные данные. См. Мой второй пример выше. При шифровании присвойте NULL столбцу открытого текста. Тогда вы знаете, какие из них были зашифрованы.

Bill Karwin 13.09.2018 23:18

Я видел это, но мне нужно зашифровать данные, и я не хочу иметь еще одну незашифрованную копию. Таким образом, второй пример не работает, и я использовал REGEXP '^ [0-9ABCDEF] + $') = 1, чтобы убедиться, что они шестнадцатеричные или нет, но все же названия некоторых компаний похожи на AAA или ABB, поэтому этот метод не работает. Я использовал varchar в этом примере, и он работал «update usersExample3 set password = aes_encrypt (password, '1234')», а пароль - varchar

user10184524 13.09.2018 23:23

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

Bill Karwin 13.09.2018 23:26

О, спасибо большое, я посмотрю на это

user10184524 13.09.2018 23:28

Важной частью теории реляционных баз данных является то, что каждый столбец должен использоваться только для одного типа данных. Не храните зашифрованные и незашифрованные данные в одном столбце. Это просто приводит к запутанным ситуациям, подобным той, в которой вы оказались. Если вы обнаружите, что изо всех сил пытаетесь создать регулярное выражение, которое соответствовало бы зашифрованным строкам, но не соответствовало бы незашифрованным строкам (что, если мой простой текст представляет собой строку из шестнадцатеричных цифр?), Тогда вы есть неоднозначная проблема. Использование разных столбцов для разных типов данных устраняет неоднозначность.

Bill Karwin 13.09.2018 23:30

Очень признателен за ответы

user10184524 13.09.2018 23:50

Другие вопросы по теме