MSSQL和ColdFusion加密转换

时间:2018-06-26 10:27:42

标签: sql-server tsql encryption coldfusion cfml

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

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

伊恩。

1 个答案:

答案 0 :(得分:2)

这似乎应该是一个简单的问题,但是正如我上面所说的,加密变得非常复杂。

对于这种特定情况,我的简短回答是“不太可能”。 CF if mat和SQL encrypt()的工作方式有所不同。即使您使用相同的密码,它们也不会加密为该值。甚至ENCRYPTBYPASSPHRASE()对其值进行加密时,在其内部也使用了一些魔术。这是一个不确定的函数,这意味着在给定相同输入的情况下,输出可能会不同。示例:尝试运行ENCRYPTBYPASSPHRASE() DECRYPTBYPASSPHRASE()`足够聪明,可以知道SQL Server的密钥派生和加密方法,因此它将能够在给定正确密钥的情况下解密该值。

这里需要注意的几件事:

1)ENCRYPTBYPASSPHRASE(N'secretkey',N'myEncryptedValue1')' 5 times. You will get 5 different values.返回ENCRYPTBYPASSPHRASE()数据类型。并且varbinary(8000)还将返回一个DECRYPTBYPASSPHRASE()。要获得可读的值,您必须将值varbinary(8000)CONVERT()返回到CAST()

2)nvarchar()仅接受ENCRYPTBYPASSPHRASE()char及其binaryN类型。因此,如果要加密任何其他类型,则必须var将其加密为二进制。

3)这使用了3DES,它比较慢并且不如“较新的” AES安全。 DES是不安全的,而3DES本质上是DES运行3倍。有更好的加密算法可用。由于3DES将在SQL2016以后弃用,我猜测cast/convert也将被弃用或更改。此外,AES虽然相当安全,但已有近20年的历史了。

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

我进行了一些测试,以证明我上面说的一些内容:

db <>提琴here

ENCRYPTBYPASSPHRASE()
     

让我们解密我们输入的内容。

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'))
;
| (No column name)  |
| :---------------- |
| myEncryptedValue1 |
| myEncryptedValue2 |
| myEncryptedValue3 |
| myEncryptedValue4 |
     

使用SELECT CONVERT(nvarchar(4000),DECRYPTBYPASSPHRASE(N'secretkey',enc)) FROM t1 ; ,我们可以在不同的SQL Server上解密该值。它不依赖服务器的证书进行加密。

现在让我们证明DECRYPTBYPASSPHRASE()是不确定的。

EncryptByPassphrase()
| enc                                                                                        |
| :----------------------------------------------------------------------------------------- |
| 0x01000000FE4E975E32AF37B6EB2E497C76C3404ED8C06E1264DCE96C1753B89812636BFE28581DA788046994 |
| 0x010000008A684062BFF1A63FC86FFDE508CA30A5130BD51459DAFD9B18CF5DD0E7775D90BC80574953C26161 |
| 0x01000000084828F7D3E2053D9E13B45B9C42A34242F6ECF5D6A9DC934EA9EE10F3BD2CFB61AA1C9EBC8DB97E |
| 0x0100000083A4E21C5F5BD8CBE65CA83DEB4A46F58D1F74768760EC28C3836E1F285E65E289A6EFB6428BD738 |
| 0x01000000DFEA8A52F63726D93E4561A19CEEFD427460E0B8617BE6633210DFFF43DD4DD083DF4CF4CB85F129 |
     

该值是用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 ; 多次加密的相同值,但导致5个不同的值。这表明SQL幕后正在发生一些魔术。我们无法在ColdFusion中解密该值,因为我们不知道在加密发生之前发生的密钥派生。

现在,所有这一切,我对您的问题“您可以在CF和SQL之间共享加密吗?”的答案更长一些。会是“取决于情况”。

显然无法使用SQL的ENCRYPTBYPASSPHRASE()与CF一起使用,因为没有可靠的方法可靠地知道用于加密值的派生密钥。但是,有很多方法可以使加密猫皮肤化。同样,您需要自己回答的主要问题是“我要保护哪种类型的数据?”。这将告诉您最终需要哪种加密类型。

由于我已经花了这么多字符,只是在使用的一种技术中只是短暂地涉及了几个功能,所以我认为这可以追溯到我最初的观点,即加密变得非常复杂很快。