MSSQL и ColdFusion Шифрование - PullRequest
0 голосов
/ 26 июня 2018

Я могу зашифровать данные, используя ColdFusion, используя 3DES (и другие алгоритмы). Я также могу зашифровать данные, используя MSSQL 3DES (encryptByPassPhrase) и EncryptByKey.

Можно ли зашифровать данные в ColdFusion с помощью 3DES (или любого другого алгоритма), а затем расшифровать данные в MSSQL? Аналогично, возможно ли зашифровать данные в MSSQL, а затем расшифровать данные в ColdFusion?

Ян.

1 Ответ

0 голосов
/ 28 июня 2018

Кажется, что это должно быть простой проблемой, но, как я сказал выше, шифрование очень быстро становится очень сложным.

Мой краткий ответ для этой конкретной ситуации - "Вероятно, нет".Существует различие в том, как CF encrypt() и SQL ENCRYPTBYPASSPHRASE() работают.Даже если вы используете одну и ту же фразу-пароль, они не будут зашифрованы до значения.Даже ENCRYPTBYPASSPHRASE() использует некоторую магию под капотом, когда шифрует значение.Это недетерминированная функция, которая означает, что при одном и том же входном сигнале выходные данные могут отличаться.Пример: попробуйте запустить ENCRYPTBYPASSPHRASE(N'secretkey',N'myEncryptedValue1')' 5 times. You will get 5 different values. DECRYPTBYPASSPHRASE () `достаточно умно, чтобы знать метод получения и шифрования ключей в SQL Server, поэтому он сможет расшифровать значение с помощью соответствующего ключа.

Здесь следует отметить несколько вещей:

1) ENCRYPTBYPASSPHRASE() возвращает тип данных varbinary(8000)DECRYPTBYPASSPHRASE() также вернет varbinary(8000).Чтобы получить читаемое значение, вам нужно CONVERT() или CAST() вернуть значение nvarchar().

2) ENCRYPTBYPASSPHRASE() принимает только типы char, binary и их N и var.Поэтому, если вы хотите зашифровать любой другой тип, вам придется cast/convert преобразовать его в двоичный файл.

3) При этом используется 3DES, который работает медленно и не так безопасен, как "более новый" AES.DES небезопасен, а 3DES - это, по сути, DES, запускаемый 3 раза.Есть лучшие алгоритмы шифрования.А поскольку после SQL2016 3DES будет устаревшим, я предполагаю, что ENCRYPT/DECRYPTBYPASSPHRASE() также будет устаревшим или измененным.Кроме того, AES, хотя и довольно безопасна, ей почти 20 лет.

4) ENCRYPTBYPASSPHRASE() запускает свою парольную фразу через функцию неопубликованного ключа для генерации 128-битного ключа.Это моя главная причина думать, что вы не сможете переключаться между CF и SQL, если используете ENCRYPTBYPASSPHRASE().Просто не существует надежного способа регенерировать фактический ключ, используемый для шифрования значения.

Я провел несколько тестов, чтобы продемонстрировать то, что я сказал выше:

db <> fiddle здесь

CREATE TABLE t1 (enc varbinary(8000));

DECLARE @secretKey Nvarchar(20) = N'secretkey' ;

INSERT INTO t1 
VALUES
    (ENCRYPTBYPASSPHRASE(@secretKey, N'myEncryptedValue1'))
  , (ENCRYPTBYPASSPHRASE(@secretKey, N'myEncryptedValue2'))
  , (ENCRYPTBYPASSPHRASE(@secretKey, N'myEncryptedValue3'))
  , (ENCRYPTBYPASSPHRASE(@secretKey, N'myEncryptedValue4'))
;

Давайте расшифруем то, что мы ввели.

SELECT CONVERT(nvarchar(4000),DECRYPTBYPASSPHRASE(N'secretkey',enc)) FROM t1 ;
| (No column name)  |
| :---------------- |
| myEncryptedValue1 |
| myEncryptedValue2 |
| myEncryptedValue3 |
| myEncryptedValue4 |

Используя DECRYPTBYPASSPHRASE(), мы можем расшифроватьзначение на разных серверах SQL.Для шифрования не нужны сертификаты сервера.

Теперь давайте покажем, что EncryptByPassphrase() недетерминирован.

TRUNCATE TABLE t1;

/* Are we empty? */
SELECT * FROM t1 ; 

|       enc        |
| No rows returned |

/* Insert the same value multiple times, encrypted. */
INSERT INTO t1 
VALUES 
    ( ENCRYPTBYPASSPHRASE('secretkey','myEncryptedValue1') ) 
  , ( ENCRYPTBYPASSPHRASE('secretkey','myEncryptedValue1') )
  , ( ENCRYPTBYPASSPHRASE('secretkey','myEncryptedValue1') ) 
  , ( ENCRYPTBYPASSPHRASE('secretkey','myEncryptedValue1') ) 
  , ( ENCRYPTBYPASSPHRASE('secretkey','myEncryptedValue1') )
;

/* Do all rows encrypt to the same value? */
SELECT * FROM t1 ; 
| enc                                                                                        |
| :----------------------------------------------------------------------------------------- |
| 0x01000000FE4E975E32AF37B6EB2E497C76C3404ED8C06E1264DCE96C1753B89812636BFE28581DA788046994 |
| 0x010000008A684062BFF1A63FC86FFDE508CA30A5130BD51459DAFD9B18CF5DD0E7775D90BC80574953C26161 |
| 0x01000000084828F7D3E2053D9E13B45B9C42A34242F6ECF5D6A9DC934EA9EE10F3BD2CFB61AA1C9EBC8DB97E |
| 0x0100000083A4E21C5F5BD8CBE65CA83DEB4A46F58D1F74768760EC28C3836E1F285E65E289A6EFB6428BD738 |
| 0x01000000DFEA8A52F63726D93E4561A19CEEFD427460E0B8617BE6633210DFFF43DD4DD083DF4CF4CB85F129 |

Это то же значение, зашифрованное с помощью ENCRYPTBYPASSPHRASE() несколько раз, но в результате получается 5 различных значений.Это показывает, что в SQL происходит некое волшебство.Мы никак не можем расшифровать это значение в ColdFusion, потому что мы не знаем, какой ключ был получен до того, как произошло шифрование.

Теперь, после всего сказанного, мой более длинный ответ на ваш вопрос о"Можете ли вы поделиться шифрованием между CF и SQL?"будет «Это зависит».

Очевидно, что использование SQL ENCRYPT/DECRYPTBYPASSPHRASE() не будет работать с CF, поскольку нет реального способа надежного определения производного ключа, используемого для шифрования значений.Тем не менее, существует множество способов обшить кошку шифрованием.И снова, главный вопрос, на который вам нужно ответить самому себе: «Какой тип данных я пытаюсь защитить?».Это скажет вам, какие типы шифрования вам в конечном итоге понадобятся.

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

...