PHPer一枚,今天在與JAVA對接的時(shí)候遇到了AES解密的問題霎肯。
百度了很多都是用的Mcrypt擴(kuò)展柑土,較為繁瑣逆济。
且PHP7.1.0 開始已經(jīng)廢棄Mcrypt擴(kuò)展酌予,使用OpenSSL擴(kuò)展可以更好的取代磺箕。
http://php.net/manual/zh/function.openssl-decrypt.php
開始吐槽一下這個(gè)坑(模擬數(shù)據(jù))
開始的已知條件
// 明文
{"parameter":{"pid":"6958"}}'
// 密文
VtV/knPbhqvaJR+76DfFLZqfdTIQcwlmQWC5cmx1v1Q_
// 密鑰
test
不知道算法模式,JAVA對接人員不在抛虫,先百度看看松靡。
看很多JAVA用的AES-128-ECB,試了下無法解密建椰,怎么辦呢雕欺?
這個(gè)時(shí)候看到了openssl_get_cipher_methods()
這個(gè)方法,解釋是:獲取可用密碼方法的列表棉姐。
既然能夠拿到所有支持的算法模式屠列,直接暴力去跑不就知道了。
$key = 'test';
$secret = 'OJuVaMm6Nb8PEJ+VUJwvBAMeHExZqfYCFvfmZ9CcmnQ_';
$types = openssl_get_cipher_methods();
foreach ($types as $type) {
echo openssl_decrypt(base64_decode($secret), $type, $key, OPENSSL_RAW_DATA);
}
輸出好像有點(diǎn)眉目
所有的結(jié)果對比只有AES-128-CBC模式解密的結(jié)果中有明文的影子伞矩,雖然不完全一致笛洛,但是基本能確定算法模式了。
但是為什么前面會是亂碼呢扭吁?查資料中發(fā)現(xiàn)了iv這個(gè)參數(shù)撞蜂,解釋是初始化向量盲镶,個(gè)人感覺類似于加鹽混淆侥袜。
搜索看有人說JAVA默認(rèn)iv是16個(gè)0,試了下溉贿,前區(qū)貌似有點(diǎn)變化枫吧。
可以確定是iv的問題了,iv的格式定義是16位的字串宇色,開始以為是二進(jìn)制的格式化字串九杂,就寫了循環(huán)來跑。
for ($i=0;$i<65536;$i++){
$bin = decbin($i);
$bin = str_pad($bin,16,"0",STR_PAD_LEFT);
...
}
/*后記:
iv并不局限于數(shù)字宣蠕,這樣可能性有很多例隆,直接暴力跑幾乎不可能。
iv在加密中看起來是對前區(qū)按順序的處理抢蚀,可以先跑前幾位慢慢確定范圍镀层。
文中有些定義僅為個(gè)人理解,如有錯(cuò)誤皿曲,歡迎評論指正唱逢。
*/
結(jié)果并沒有拿到想要的明文。
這個(gè)時(shí)候?qū)尤松暇€了屋休,問他有沒有設(shè)置iv坞古,說沒有。我就非常疑惑了劫樟,直接要了JAVA處理加密的源碼痪枫。
順著方法找到了這個(gè)
然后就發(fā)現(xiàn)了這個(gè):
拿到了iv织堂,在PHP中執(zhí)行解密,解決了奶陈,寫完文章下班捧挺!
echo openssl_decrypt(base64_decode($secret), 'AES-128-CBC', $key, OPENSSL_RAW_DATA,'1234567890123456')."\r\n";