sql-server - MSSQL & ColdFusion 加密转换
问题描述
我能够使用 3DES(和其他算法)使用 ColdFusion 加密数据。我还能够使用 MSSQL 3DES ( encryptByPassPhrase
) 和EncryptByKey
.
是否可以使用 3DES(或任何算法)在 ColdFusion 中加密数据,然后在 MSSQL 中解密数据?同样,是否可以在 MSSQL 中加密数据然后在 ColdFusion 中解密数据?
伊恩。
解决方案
这似乎应该是一个简单的问题,但正如我上面所说,加密很快就会变得非常复杂。
对于这种特定情况,我的简短回答是“可能不会”。encrypt()
CF和 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 次。有更好的加密算法可用。而且由于 3DES 将在 SQL2016 之后被弃用,我猜它ENCRYPT/DECRYPTBYPASSPHRASE()
也将被弃用或更改。此外,AES 虽然相当安全,但已经有将近 20 年的历史了。
4)ENCRYPTBYPASSPHRASE()
通过非公开密钥派生函数运行其密码以生成 128 位密钥。这是我认为如果使用ENCRYPTBYPASSPHRASE()
. 根本没有可靠的方法来重新生成用于加密值的实际密钥。
我进行了一些测试来演示我上面所说的一些内容:
db<>在这里摆弄
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 ;
| (无列名) | | :---------------- | | 我的加密值1 | | 我的加密值2 | | 我的加密值3 | | 我的加密值4 |使用
DECRYPTBYPASSPHRASE()
,我们可以解密不同 SQL Server 上的值。它不依赖服务器的证书来进行加密。
现在让我们证明它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 ;
| 编码 | | :------------------------------------------------ ---------------------------------------------------- | | 0x01000000FE4E975E32AF37B6EB2E497C76C3404ED8C06E1264DCE96C1753B89812636BFE28581DA788046994 | | 0x010000008A684062BFF1A63FC86FFDE508CA30A5130BD51459DAFD9B18CF5DD0E7775D90BC80574953C26161 | | 0x01000000084828F7D3E2053D9E13B45B9C42A34242F6ECF5D6A9DC934EA9EE10F3BD2CFB61AA1C9EBC8DB97E | | 0x0100000083A4E21C5F5BD8CBE65CA83DEB4A46F58D1F74768760EC28C3836E1F285E65E289A6EFB6428BD738 | | 0x01000000DFEA8A52F63726D93E4561A19CEEFD427460E0B8617BE6633210DFFF43DD4DD083DF4CF4CB85F129 |
ENCRYPTBYPASSPHRASE()
这是多次加密的相同值,但会产生 5 个不同的值。这表明 SQL 的幕后发生了一些神奇的事情。我们无法在 ColdFusion 中解密该值,因为我们不知道在加密发生之前发生的密钥派生。
现在,所有这一切,我对你的问题的更长的回答“你能在 CF 和 SQL 之间共享加密吗?” 将是“视情况而定”。
显然,使用 SQLENCRYPT/DECRYPTBYPASSPHRASE()
不适用于 CF,因为没有真正的方法可以可靠地知道用于加密值的派生密钥。但是,有很多方法可以剥去加密猫的皮肤。同样,您需要自己回答的主要问题是“我要保护什么类型的数据?”。这将告诉您最终需要哪种类型的加密。
由于我已经使用了这么多字符,只是简单地触及了您正在使用的一种技术中的几个功能,我认为这又回到了我最初的观点,即加密很快就会变得非常复杂。
推荐阅读
- javascript - 第二个列表的Droplist动态更改值 - 问题
- reactjs - 反应类名命名约定
- python - Pandas 中的向量化字符串比较
- flutter - 颤振卡颜色
- d3.js - D3.JS 如何定位
? - objective-c - weakSelf 在块内为零
- c - 如何使用 cloudamqp 以 C 语言对 paho mqtt 订阅者客户端进行身份验证?
- actions-on-google - 谷歌智能家居中的令牌交换请求出错
- python - 如何将持续时间格式转换为秒?
- scala - Scala - 在组中具有单个值的 KeyValueGroupedDataset 上的 reduceGroups