摘要:填充算法與基本上是可以通用的。年,高級加密標準已然成為對稱密鑰加密中最流行的算法之一。常用庫介紹是一個功能強大的加密算法擴展庫。為提供了各種各樣的加密算法。目前已支持的算法包括是使用編寫的加密工具包。
本文示例代碼詳見:https://github.com/52fhy/cryp...
DESDES全稱為Data Encryption Standard,即數據加密標準,是一種使用密鑰加密的塊算法,1977年被美國聯邦政府的國家標準局確定為聯邦資料處理標準(FIPS),并授權在非密級政府通信中使用,隨后該算法在國際上廣泛流傳開來。
DES使用簡介使用DES需要設置加密內容、加密key、加密混淆向量iv、分組密碼模式、填充模式。
加密內容:
給定的加密的數據。如果數據長度不是 n*分組大小,則在其后使用 "0" 補齊。
加密Key:
加密密鑰。 如果密鑰長度不是該算法所能夠支持的有效長度,需要填充。如果密鑰長度過長,需要截取。
加密iv:
用于CBC, CFB, OFB模式,在ECB模式里不是必須的。
分組密碼模式:
常見的分組密碼模式有:CBC, OFB,CFB 和 ECB。
填充模式:
Pkcs5、Pkcs7。
PKCS5Padding與PKCS7Padding基本上是可以通用的。在PKCS5Padding中,明確定義Block的大小是8位,而在PKCS7Padding定義中,對于塊的大小是不確定的,可以在1-255之間(塊長度超出255的尚待研究),填充值的算法都是一樣的:
pad = k - (l mod k) //k=塊大小,l=數據長度,如果k=8, l=9,則需要填充額外的7個byte的7
可以得出:Pkcs5是Pkcs7的特例(Block的大小始終是8位)。當Block的大小始終是8位的時候,Pkcs5和Pkcs7是一樣的。(參考)
填充算法實現:
PHP
function pkcs5_pad($text) { $pad = 8 - (strlen($text) % 8); //$pad = 8 - (strlen($text) & 7); //也可以使用這種方法 return $text . str_repeat(chr($pad), $pad); } function pkcs7_pad ($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); }
反填充(去掉填充的字符)只需要根據解密后內容最后一個字符,就知道填充了什么、填充了幾個,然后截取掉即可:
function _unpad($text){ $pad = ord(substr($text, -1));//取最后一個字符的ASCII 碼值 if ($pad < 1 || $pad > strlen($text)) { $pad = 0; } return substr($text, 0, (strlen($text) - $pad)); }
Python
from Crypto.Cipher import AES def pkcs7_pad(str): x = AES.block_size - (len(str) % AES.block_size) if x != 0: str = str + chr(x)*x return str def _unpad(msg): paddingLen = ord(msg[len(msg)-1]) return msg[0:-paddingLen]加密解密步驟
加密步驟(以PHP的擴展mcrypt為例):
1、獲得加密算法的分組大小(mcrypt_get_block_size);
2、被加密的明文使用Pkcs5或Pkcs7填充;
3、加密密鑰key截取或填充至8位;
4、加密向量iv設置;
5、打開指定算法和模式對應的模塊,返回加密描述符td(mcrypt_module_open);
6、使用td、key、iv初始化加密所需的緩沖區 (mcrypt_generic_init);
7、加密數據(mcrypt_generic);
8、清理的加密描述符td的緩沖區(mcrypt_generic_deinit);
9、釋放加密描述符td(mcrypt_module_close);
10、返回base64_encode的加密結果,可選。
解密步驟(以PHP的擴展mcrypt為例):
1、base64_decode解碼,如果加密使用了base64_encode;
2、加密密鑰key截取或填充至8位;
3、加密向量iv設置;
4、打開指定算法和模式對應的模塊,返回加密描述符td(mcrypt_module_open);
5、使用td、key、iv初始化加密所需的緩沖區 (mcrypt_generic_init);
6、解密數據(mdecrypt_generic);
7、清理的加密描述符td的緩沖區(mcrypt_generic_deinit);
8、釋放加密描述符td(mcrypt_module_close);
9、使用Pkcs5去掉填充的內容,返回解密后的結果。
使用DES需要注意下面幾點:
1) 確保都使用DES + ECB;
2) 確保明文填充都使用的是Pkcs5或者Pkcs7,此時兩者效果一致;
3) 加密key在DES長度必須是8字節(bytes);如果不夠長必須填充,過長必須截取;
4) 加密向量iv與加密key有同樣的約定;
5) 注意加密結果建議都使用base64編碼。
只有以上都保持一樣,各個語言里最終加密的密文才能保持一致,否則會出現:
1) 每次加密的密文不一樣,但是能解密;(iv隨機生成導致的)
2) 不同語言加密出來的密文不一致。
示例:
Crypt_DES.php
setKey("pwd"); //$des->setIV("