相同密码key,同一个明文,通过AES加密后,可以产生多个不同密文,测试代码如下:
declare @varBi0 varbinary(200)
set @varBi0 = EncryptByKey(Key_GUID('SymmetricByPW'), convert(varchar(200),'12345678'));
declare @varBi1 varbinary(200)
set @varBi1 = EncryptByKey(Key_GUID('SymmetricByPW'), convert(varchar(200),'12345678'));
declare @varBi3 varbinary(200)
set @varBi2 = EncryptByKey(Key_GUID('SymmetricByPW'), convert(varchar(200),'12345678'));
输出结果如下:
@varBi0 = 0x00E87406A93C4643815DD2C78B175EFA0100000079DE70E53D4826B955C401992376CF1E6DDAB6C6972C24F81EF79E1FA2C7C2E819F1582FF249BA07AB32397412469FAA
@varBi1 = 0x00E87406A93C4643815DD2C78B175EFA010000004D42BF401511324FD4C6C873BC3FD314B2E0F45C1CA58D065EFE3BEB74C0EF43EDA1E3D0C65246034D9DDE7A98CEEB89
@varBi2 = 0x00E87406A93C4643815DD2C78B175EFA01000000B17606E5E86DE4518B758BFA4CF3D3B95F3B94E16821288F01F824454BF7947E1318295C344951D337699D36B058915C
可以看到输出的三个参数都不一样。通过decryptbykey函数解密可得到相同明文“12345678”。
那么如果数据库里存储的数据密文num_encrypt,如varBi0,varBi1,varBi2等。现在需要按照明文查找内容,如果每一条都要解密后再查询效率很低,sql如下:
select * from table where convert (varchar(200),decryptbykey(num_encrypt)) in ('12345678','','','')
如果先把明文加密,比对密文,那么每次加密后密文又不一样,查找内容为空。
那么有什么办法能提高查询效率呢?我这里采用的折中方法——“将明文加*存储,如12345678,存储成5678,先匹配出后4位一致的,缩小范围,再查找解密后一致的”
select * from (SELECT * FROM table
where right([num],4) in ('5678','')) b
where convert(varchar(200),decryptbykey(b.num_encrypt)) in ('12345678')
解决方案比较曲折,希望有更好方法的小伙伴留言解答,天天给你点赞哦!
参考内容:
密文不同主要有以下原因:
1.加密key的比特数不同。有(128,192, 256),加密key比特数不一样,密文就不可能一样。
2.明文填充模式不一样。因为AES是分组的,每32字节一组,不满32字节的明文要填充到32字节。不同的填充方法肯定会造成密文的不一致。
3.使用的AES加密模式不一样,有四种模式(ECB、CBC、CFB、OFB) ,不同模式加密得到的密文显然不会一样
4.还有一个就是是否使用初始化向量