我能够使用3DES(和其他算法)使用ColdFusion加密数据。我还能够使用MSSQL 3DES(encryptByPassPhrase
)和EncryptByKey
对数据进行加密。
是否可以使用3DES(或任何算法)在ColdFusion中加密数据,然后在MSSQL中解密数据? 同样,是否可以在MSSQL中加密数据然后在ColdFusion中解密数据?
伊恩。
答案 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
及其binary
和N
类型。因此,如果要加密任何其他类型,则必须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一起使用,因为没有可靠的方法可靠地知道用于加密值的派生密钥。但是,有很多方法可以使加密猫皮肤化。同样,您需要自己回答的主要问题是“我要保护哪种类型的数据?”。这将告诉您最终需要哪种加密类型。
由于我已经花了这么多字符,只是在使用的一种技术中只是短暂地涉及了几个功能,所以我认为这可以追溯到我最初的观点,即加密变得非常复杂很快。