互联网的软件设计一定少不了加密算法,并且大量使用的都会是对称加密,比较常见的对称加密有:DES、3DES、RC4、AES等等;
加密算法都有几个共同的要点:
对于加密模式,比如DES,也会有ECB、CBC等不同的区分,它们都是标准的;
Windows加密库中,默认则是CBC模式,也可以手工设置;
Openssl库要更明显一点,它的函数名里面就写明了,比如:DES_ncbc_encrypt,一看就知道是cbc模式;
JAVA里面也比较清楚:Cipher c = Cipher.getInstance(”DES/CBC/PKCS5Padding”); 也可以看到是CBC模式
各种加密模式有什么不同呢:(为了方便,这里的加密key都取64位)
最古老,最简单的模式,将加密的数据分成若干组,每组的大小跟加密密钥长度相同;
然后每组都用相同的密钥加密, 比如DES算法, 如果最后一个分组长度不够64位,要补齐64位;
定义:
Enc(X,Y)是加密函数
Dec(X,Y)是解密函数
Key是加密密钥;
Pi ( i = 0,1…n)是明文块,大小为64bit;
Ci ( i = 0,1…n)是密文块,大小为64bit;
ECB加密算法可表示为:
Ci = Enc(Key, Pi)
ECB解密算法可以表示为:
Pi = Dec(Key,Ci)
算法 特点:
与ECB模式最大的不同是加入了初始向量
定义:
Enc(X,Y)是加密函数
Dec(X,Y)是解密函数
Key是加密密钥;
Pi ( i = 0,1…n)是明文块,大小为64bit;
Ci ( i = 0,1…n)是密文块,大小为64bit;
XOR(X,Y)是异或运算;
IV是初始向量(一般为64位);
ECB加密算法可表示为:
C0 = Enc(Key, XOR(IV, P0)
Ci = Enc(Key, XOR(Ci-1, Pi)
ECB解密算法可以表示为:
P0 = XOR(IV, Dec(Key, C0))
Pi = XOR(Ci-1, Dec(Key,Ci))
算法特点:
加密反馈模式克服了需要等待8个字节才能加密的缺点,它采用了分组密码作为流密码的密钥流生成器;
定义:
Enc(X,Y)是加密函数
Dec(X,Y)是解密函数
Key是加密密钥;
Pi ( i = 0,1…n)是明文块,大小为64bit;
Ci ( i = 0,1…n)是密文块,大小为64bit;
Si ( i = 0,1…n),大小为8bit,n个连续的Si组成加密位移寄存器,一般n=8;
Oi = Enc(Key, Si);
Lef(x) 为取数据x的最左8个bit位;
A(x,y)为合并x左移8位,空位用y填充
CFB加密算法可表示为:
S0 = IV;
Oi = Enc(Key, Si);
Ci = XOR( Ci, Lef(Oi));
Si = A(Si-1, Ci);
CFB解密算法可表示为:
S0 = IV;
Oi = Enc(Key, Si);
Ci = XOR( Ci, Lef(Oi));
Si = A(Si-1, Ci);
特点:
与CFB模式不同之处在于, 加密位移寄存器与密文无关了,仅与加密key和加密算法有关;
做法是不再把密文输入到加密移位寄存器,而是把输出的分组密文(Oi)输入到一位寄存器;
定义:
Enc(X,Y)是加密函数
Dec(X,Y)是解密函数
Key是加密密钥;
Pi ( i = 0,1…n)是明文块,大小为64bit;
Ci ( i = 0,1…n)是密文块,大小为64bit;
Si ( i = 0,1…n),大小为8bit,n个连续的Si组成加密位移寄存器,一般n=8;
Oi = Enc(Key, Si);
Lef(x) 为取数据x的最左8个bit位;
A(x,y)为合并x左移8位,空位用y填充
CFB加密算法可表示为:
S0 = IV;
Oi = Enc(Key, Si);
Ci = XOR( Ci, Lef(Oi));
Si = A(Si-1, Oi); 注意这里与CFB模式的不同
CFB解密算法可表示为:
S0 = IV;
Oi = Enc(Key, Si);
Ci = XOR( Ci, Lef(Oi));
Si = A(Si-1, Oi);
特点:
CryptGetKeyParam可以对HCRYPTKEY对象的各种参数进行查询,包括加密模式、padding方式等;但这个函数不能用于查询加密key的明文;
但如果需要看到真正加密的key是什么,则需要另外的API:CryptExportKey,选择PLAINTEXTKEYBLOB方式进行导出可以得到key的明文;
当两个封装好的加密算法对8byte数据进行DES加密时,如果加密出来的结果是一样的,千万不要认为这两个算法可以互换;
因为ECB模式,和向量全为0的CBC模式得到的密文前8byte,确实是一样,但后面的密文就不一样了;
使用加密以前确定你理解了它;
ECB是不推荐的方式,Key相同时,相同的明文在不同的时候产生相同的明文,容易遭到字典攻击;
CBC由于加入了向量参数,一定程度上抵御了字典工具,但缺点也随之而来,一旦中间一个数据出错或丢失,后面的数据将受到影响;
CFB与CBC类似,好处是明文和密文不用是8bit的整数倍,中间一个数据出错,只影响后面的几个块的数据;
OFB比CFB方式,一旦一个数据出错,不会影响后面的数据,但安全性降低;
因此,推荐使用CFB方式,但每个数据包单独加密,否则一个数据包丢失,需要做很多容错处理;
当然,具体问题也要具体分析,对于只需要”特定安全性”①,不需要”计算安全性”以上的软件,也可以使用ECB模式;