您好,登錄后才能下訂單哦!
PHP中怎么實現(xiàn)aes加密解密,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
aes加密解密過程
用戶數(shù)據(jù)應(yīng)經(jīng)過加密再傳輸,此文檔為aes128加密(cbc模式)的說明 摘要算法為SHA-512
加密:
生成16位iv向量,使用該iv以及密鑰加密原文
將加密后的真實密文與iv拼接: iv+真實密文
將與iv拼接后的密文用SHA-512 HMAC生成摘要信息(128位),與密文拼接: HMAC+base64后的密文,得到最終的密文
解密:
分離出hmac與密文,可以自行進行摘要檢測,可以防止時序攻擊.
得到拼接了iv的原文.分離出iv以及真實原文
使用密鑰以及iv進行解碼,得到原文
加密舉例 php版本
/*****加密過程*****/
$str = "Hello World";
//1.使用16位密鑰
$key = '12345678901234ab';
//2.生成16位iv 算法自定,示例中直接指定
//$iv = openssl_random_pseudo_bytes(16); //12345678ss1234ab
$iv="12345678ss1234ab";
//3.加密 IvdA7oP8BInWa5shY+LCyQ==
$secert_str = openssl_encrypt($str, 'AES-128-CBC', $key, 0, $iv);
$secert_str = $iv . $secert_str; //4.將iv與密文拼接 12345678ss1234abIvdA7oP8BInWa5shY+LCyQ==
//5.base64_encode 考慮語言兼容性問題,該步驟取消
//6.用SHA-512生成摘要 128位16進制 3b2106c05b46b603969c2b1bc7503c8233d209dcd204b098b33ba704507315480e03e499e0082e8842b60baa01f522d7c0342d75196d18d3514d37c58e31d733
$hmac = hash_hmac('sha512', $secert_str, $key, false);
//7.拼接摘要,得到密文
$secert_str = $hmac . $secert_str;
return urlencode($secert_str);
解密舉例
$str=rawurldecode($str);
$len = mb_strlen($secert_str);
$ori_hmac = substr($secert_str, 0, 128);
$data = substr($secert_str, 128, $len);
//2.驗證摘要
$local_hmac = hash_hmac('sha512', $data, $key, false);
$diff = 0;
for ($i = 0; $i < 128; $i++) {
$diff |= ord($ori_hmac[$i]) ^ ord($local_hmac[$i]);
}
if ($diff !== 0) {
return FALSE;
}
//3.分離iv
$len = mb_strlen($data);
$iv = substr($data, 0, 16);
$data = substr($data, 16, $len);
//4.解密,獲得原文
$data = openssl_decrypt($data, 'AES-128-CBC', $key, 0, $iv);
java加解密類
package main;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.util.encoders.Hex;
public class AESUtil {
/**
* aes/128/cbc加密
* @param sSrc 明文
* @param sKey 密鑰
* @param sIv 向量
* @return
* @throws Exception
*/
public static String Encrypt(String sSrc, String sKey, String sIv) throws Exception {
if (sKey == null) {
System.out.print("Key為空null");
return null;
}
// 判斷Key是否為16位
if (sKey.length() != 16) {
System.out.print("Key長度不是16位");
return null;
}
//1.加密
byte[] raw = sKey.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//aes-cbc-pkcs5(pkcs5與pkcs7通用)
IvParameterSpec iv = new IvParameterSpec(sIv.getBytes());//使用CBC模式,需要一個向量iv,可增加加密算法的強度
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(sSrc.getBytes("UTF-8"));
String encryptedString = new String(Base64.encodeBase64(encrypted));
//2.拼接iv
encryptedString = sIv + encryptedString;
//3.sha512
String hmac = encodeHmacSHA512(encryptedString, sKey);
//4.拼接摘要
encryptedString = hmac+encryptedString;
//5.urlencode
encryptedString = URLEncoder.encode(encryptedString);
return encryptedString;
}
// 解密
/**
*
* @param sSrc 密文
* @param sKey 密鑰
* @return
* @throws Exception
*/
public static String Decrypt(String sSrc, String sKey) throws Exception {
try{
//0.urldecode
sSrc=URLDecoder.decode(sSrc);
//1.分離摘要
System.out.println(sSrc);
String hmac=sSrc.substring(0,128);
String data=sSrc.substring(128,sSrc.length());
//2.驗證摘要
//3.分離iv
String sIv=data.substring(0,16);
String str=data.substring(16,data.length());
//4.解密
byte[] raw = sKey.getBytes("UTF-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(sIv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = Base64.decodeBase64(str.getBytes());
try {
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original);
return originalString;
} catch (Exception e) {
System.out.println(e.toString());
return null;
}
}catch (Exception ex){
System.out.println(ex.toString());
return null;
}
}
/**
* HmacSHA512消息摘要
*
* @param data 待做摘要處理的數(shù)據(jù)
* @param key 密鑰
* @return
*/
public static String encodeHmacSHA512(String data, String key) throws Exception {
byte[] bytesKey = key.getBytes();
SecretKeySpec secretKey = new SecretKeySpec(bytesKey, "HmacSHA512");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
final byte[] macData = mac.doFinal(data.getBytes());
byte[] hex = new Hex().encode(macData);
String result = new String(hex, "ISO-8859-1");
return result;
}
}
java實例
import main.AESUtil;
public class Main {
public static void main(String[] args) {
//key
String cKey = "12345678901234ab";
// 需要加密的字串
String cSrc = "Hello World";
//iv 16位 算法自定 實例中直接指定
String sIv = "12345678ss1234ab";
String enString;
String deString;
try {
enString = AESUtil.Encrypt(cSrc, cKey, sIv);
System.out.println("加密后的字串是:" + enString);
deString = AESUtil.Decrypt("3b2106c05b46b603969c2b1bc7503c8233d209dcd204b098b33ba704507315480e03e499e0082e8842b60baa01f522d7c0342d75196d18d3514d37c58e31d73312345678ss1234abIvdA7oP8BInWa5shY+LCyQ==", cKey);
System.out.println("解密后的字串是:" + deString);
} catch (Exception e) {
e.printStackTrace();
}
}
}
關(guān)于PHP中怎么實現(xiàn)aes加密解密問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。