摘要:密鑰長(zhǎng)度是位,超過位數(shù)密鑰被忽略。跨語(yǔ)言做加密解密經(jīng)常會(huì)出現(xiàn)問題,往往是填充方式不對(duì)編碼不一致或者加密解密模式?jīng)]有對(duì)應(yīng)上造成。是為了兼容用加密的結(jié)果。
最近在對(duì)接客戶的CRM系統(tǒng),獲取令牌時(shí),要用DES方式加密解密,由于之前沒有搞錯(cuò)這種加密方式,經(jīng)過請(qǐng)教了“百度”和“谷歌”兩個(gè)老師后,結(jié)合了多篇文檔內(nèi)容后,終于實(shí)現(xiàn)了。
一、DES介紹DES 是對(duì)稱性加密里面常見一種,全稱為 Data Encryption Standard,即數(shù)據(jù)加密標(biāo)準(zhǔn),是一種使用密鑰加密的塊算法。密鑰長(zhǎng)度是64位(bit),超過位數(shù)密鑰被忽略。所謂對(duì)稱性加密即加密和解密密鑰相同,對(duì)稱性加密一般會(huì)按照固定長(zhǎng)度,把待加密字符串分成塊,不足一整塊或者剛好最后有特殊填充字符。
跨語(yǔ)言做 DES 加密解密經(jīng)常會(huì)出現(xiàn)問題,往往是填充方式不對(duì)、編碼不一致或者加密解密模式?jīng)]有對(duì)應(yīng)上造成。
常見的填充模式有: pkcs5、pkcs7、iso10126、ansix923、zero。
加密模式有:DES-ECB、DES-CBC、DES-CTR、DES-OFB、DES-CFB。
加密用到的方法:openssl_encrypt($data, $method, $password, $options, $iv)
參數(shù)說(shuō)明:
$data 加密明文
$method 加密方法
DES-ECB
DES-CBC
DES-CTR
DES-OFB
DES-CFB
$passwd 加密密鑰[密碼]
$options 數(shù)據(jù)格式選項(xiàng)(可選)【選項(xiàng)有:】
0
OPENSSL_RAW_DATA=1
OPENSSL_ZERO_PADDING=2
OPENSSL_NO_PADDING=3
$iv 密初始化向量(可選)
openssl_decrypt($data, $method, $password, $options, $iv)
參數(shù)說(shuō)明:
$data 要解密的數(shù)據(jù)
其他參數(shù)同加密方法
三、用法案例:參數(shù):
$data = "1234567887654321";//加密明文 $method = "DES-ECB";//加密方法 $passwd = "12344321";//加密密鑰 $options = 0;//數(shù)據(jù)格式選項(xiàng)(可選) $iv = "";//加密初始化向量(可選)(1) 默認(rèn)填充方式:
加密:
$result = openssl_encrypt($data, $method, $passwd, $options); var_dump($result);
結(jié)果:
string(32) "kQYOdswcm9I5elv2wdJucplqAgqDNqXg"
解密
$result = "kQYOdswcm9I5elv2wdJucplqAgqDNqXg"; var_dump(openssl_decrypt($result, $method, $passwd, 0));
結(jié)果:
string(16) "1234567887654321"(2) OPENSSL_RAW_DATA方式【會(huì)用PKCS#7進(jìn)行補(bǔ)位】
加密
$result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA); var_dump($result);
結(jié)果:
string(24) "?v???9z[???nr?j ?6??"
我們可以看到結(jié)果是亂碼的,這時(shí)我們需要base64一下
$result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA); var_dump(base64_encode($result));
這時(shí)結(jié)果是
string(32) "kQYOdswcm9I5elv2wdJucplqAgqDNqXg"
解密
result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA); var_dump(openssl_decrypt($result, $method, $passwd,OPENSSL_RAW_DATA));
結(jié)果:
string(16) "1234567887654321"
我們可以看到:默認(rèn)填充方式與OPENSSL_RAW_DATA,這兩種方式加密結(jié)果是一樣的
(3) OPENSSL_ZERO_PADDING方式看字面意思,是用0填充,但是測(cè)試并不起作用
加密
$result = openssl_encrypt($data, $method, $passwd, OPENSSL_ZERO_PADDING); var_dump($result);
結(jié)果:
string(24) "kQYOdswcm9I5elv2wdJucg=="
解密:
$result = openssl_encrypt($data, $method, $passwd, OPENSSL_ZERO_PADDING); var_dump(openssl_decrypt($result, $method, $passwd,OPENSSL_ZERO_PADDING));
結(jié)果:
string(16) "1234567887654321"(4) OPENSSL_NO_PADDING【不填充,需要手動(dòng)填充】
在openssl_encrypt前加上填充過程
加密
$str_padded = $data; if (strlen($str_padded) % 16) { $str_padded = str_pad($str_padded,strlen($str_padded) + 16 - strlen($str_padded) % 16, "