前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA与PHP之间进行aes加密解密

JAVA与PHP之间进行aes加密解密

作者头像
BUG弄潮儿
发布2022-06-30 14:37:49
2.5K0
发布2022-06-30 14:37:49
举报
文章被收录于专栏:JAVA乐园

aes加密解密过程

用户数据应经过加密再传输,此文档为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 .

//5.base64_encode 考虑语言兼容性问题,该步骤取消

//6.用SHA-512生成摘要 128位16进制 3b2106c05b46b603969c2b1bc7503c8233d209dcd204b098b33ba704507315480e03e499e0082e8842b60baa01f522d7c0342d75196d18d3514d37c58e31d733

hmac = hash_hmac('sha512', secert_str,

//7.拼接摘要,得到密文

secert_str = hmac .

return urlencode($secert_str);

解密举例

str=rawurldecode(str);

len = mb_strlen(secert_str);

ori_hmac = substr(secert_str, 0, 128);

data = substr(secert_str, 128,

//2.验证摘要

local_hmac = hash_hmac('sha512', data,

$diff = 0;

for (i = 0; i < 128;

diff |= ord(ori_hmac[i]) ^ ord(local_hmac[

}

if ($diff !== 0) {

return FALSE;

}

//3.分离iv

len = mb_strlen(data);

iv = substr(data, 0, 16);

data = substr(data, 16,

//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 待做摘要处理的数据

* @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();

}

}

}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-12-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 BUG弄潮儿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档