sql-server - MSSQL & ColdFusion 加密转换

标签 sql-server tsql encryption coldfusion cfml

我能够使用 ColdFusion 使用 3DES(和其他算法)加密数据。我还能够使用 MSSQL 3DES (encryptByPassPhrase) 和 EncryptByKey 加密数据。

是否可以使用 3DES(或任何算法)在 ColdFusion 中加密数据,然后在 MSSQL 中解密数据? 同样,是否可以在 MSSQL 中加密数据然后在 ColdFusion 中解密数据?

伊恩。

最佳答案

这看起来应该是一个简单的问题,但正如我上面所说,加密很快就会变得非常复杂。

对于这种特定情况,我的简短回答是“可能不会”。 CF 的 encrypt() 和 SQL 的 ENCRYPTBYPASSPHRASE() 工作方式有所不同。即使您使用相同的密码,它们也不会加密到该值。甚至 ENCRYPTBYPASSPHRASE() 在加密值时也使用了一些隐藏的魔法。它是一个非确定性函数,这意味着给定相同的输入,输出可能不同。示例:尝试运行 ENCRYPTBYPASSPHRASE(N'secretkey',N'myEncryptedValue1')' 5 次。您将获得 5 个不同的值。DECRYPTBYPASSPHRASE()` 足够聪明,知道 SQL Server 的 key 派生和加密方法,因此它能够解密给定正确 key 的值。

这里有几点需要注意:

1) ENCRYPTBYPASSPHRASE() 返回一个 varbinary(8000) 数据类型。 DECRYPTBYPASSPHRASE() 也会返回一个 varbinary(8000)。要获得可读值,您必须通过 CONVERT()CAST() 将值返回到 nvarchar()

2) ENCRYPTBYPASSPHRASE() 只接受charbinary 及其Nvar 类型。因此,如果您想加密任何其他类型,则必须将其转换/转换为二进制。

3) 这使用 3DES,速度慢且不如“较新”的 AES 安全。 DES 是不安全的,3DES 本质上是 DES 运行 3 次。有更好的加密算法可用。由于 3DES 将在 SQL2016 之后被弃用,我猜测 ENCRYPT/DECRYPTBYPASSPHRASE() 也将被弃用或更改。此外,AES 虽然非常安全,但已有将近 20 年的历史。

4) ENCRYPTBYPASSPHRASE() 通过未发布的 key 派生函数运行其密码短语以生成 128 位 key 。这是我认为如果使用 ENCRYPTBYPASSPHRASE() 将无法在 CF 和 SQL 之间来回切换的主要原因。根本没有可靠的方法来重新生成用于加密值的实际 key 。

我运行了几个测试来证明我上面所说的一些内容:

db<>fiddle here

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'))
;

Let's decrypt what we've entered.

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

Using DECRYPTBYPASSPHRASE(), we can decrypt the value on different SQL Servers. It doesn't rely on the server's certificates to do the encryption.

现在让我们证明 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 |

That's the same value encrypted with ENCRYPTBYPASSPHRASE() multiple times, but resulting in 5 different values. This shows that there's some magic going on behind the scenes in SQL. There's no way we can decrypt that value in ColdFusion, because we don't know the key derivation that happened before the encryption occurred.

现在,综上所述,我对你的问题“你能在 CF 和 SQL 之间共享加密吗?”的问题给出了更长的回答。将是“视情况而定。”

显然使用 SQL 的 ENCRYPT/DECRYPTBYPASSPHRASE() 不适用于 CF,因为没有真正的方法可以可靠地知道用于加密值的派生 key 。但是,有很多方法可以给加密猫换皮。同样,您需要自己回答的主要问题是“我要保护什么类型的数据?”。这将告诉您最终需要什么类型的加密。

而且由于我已经花了这么多字符只是简单地介绍了您正在使用的一种技术中的几个功能,我认为这又回到了我最初的观点,即加密变得非常复杂非常迅速地。

关于sql-server - MSSQL & ColdFusion 加密转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51040621/

相关文章:

encryption - 密码处理最佳实践?

javax.crypto.BadPaddingException : pad block corrupted sometimes

sql-server - SQL Server 2014 合并重叠的日期范围

sql - 需要有关 Merge 语句的帮助

SQL Server FTS : Ranking is a bit strange

列的 SQL MAX(包括其主键)

java - 如何使用 BouncyCaSTLe 轻量级 API 在 GCM 密码中利用 AAD

c# - 数据集中关系的目的是什么?

sql-server - 为什么 "(800) 555-1212"不适合 varchar(20) 字段?

sql-server - SQL Server 2012 文件流 : An error occurred during the drop table operation on a FileTable object