block cipher已经有很多了,3DES、blowfish、AES...
加密算法给出的是:给定key和plaintext,如何变换得到ciphertext。
从加密算法开始,如何得到一个加密文件的可用程序,还有一段路要走,主要面对的问题是:
1,从文件到plaintext,文件的大小通常不是一个block大小,那么,如何分块,不同块之间如何处理,如果不能分成完整的块怎么办?
2,从口令(password或者passphrase)到key,用户的加密解密口令通常是一个字符串,如“fotally”,怎么从口令得到一个key?
RSA Labs的标准PKCS#5,给出了一些推荐做法,见http://www.rsa.com/rsalabs/node.asp?id=2127。
解决方法如下:
一、文件分块、填充、加密模式
文件的分块很容易,按照cipher block大小分块就行了。
加密模式的选择很重要,ECB、CBC、OFB、Counter等等,各有优缺。见http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
OFB、Counter这些模式,实际上是将block cipher转变成了stream cipher,因此padding就没必要了。
对于常用的CBC模式,padding是不可避免的,如果没有特殊理由,一般就用PKCS#5的填充模式。
关于填充模式更多的可参见http://en.wikipedia.org/wiki/Padding_(cryptography)以及http://www.di-mgt.com.au/cryptopad.html
二、从口令得到key
从口令得到key的方法称作Key Derivation Function,PKCS#5推荐的Password-Based Key Derivation Function是PBKDF2(http://en.wikipedia.org/wiki/PBKDF2),基本思想是对password进行hash得到key,有两个要点
1,salt,不解释
2,key stretching,将hash重复若干次(1,000次以上)。这样做的目的在于,正常应用场景下,从口令得到key是一个一次性的操作,增加复杂度不会对应用产生影响;而对于敌手,这样做将极大的增加敌手的计算复杂度。简而言之,这是一个从工程角度增加安全性的方法。
更多KDF信息可以参见http://www.di-mgt.com.au/cryptokeys.html,另,http://www.di-mgt.com.au/cryptoKDFs.html给出了目前常见的KDF的简介。
对于文件加密,通常可以使用CBC模式,ECB模式肯定不行。Bruce Schneider在Applied Cryptography中也推荐使用CBC模式。由于需要padding,加密以后的密文文件比明文文件要大一些,最大可能会增加一个block(对于AES,这是128bit即16bytes)。
上面文章中提到说Schneider的新书里面推荐Counter模式,我沒有确认,不过Counter模式的好处是显而易见的(可以随机访问呀)。