PHP AES-GCM-256加密有java示例代码 但就是php加密的结果不对
1. 问题描述?
这是三方文档提供的java代码示例
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
/**
* AES-GCM-256 工具类
* 加解密方法中已调用 Base64 方法
*/
public class AesGcm256Util {
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
public static final int NONCE_BIT_SIZE = 128;
public static final int MAC_BIT_SIZE = 128;
public static final int KEY_BIT_SIZE = 256;
private AesGcm256Util() {
}
/**
* 创建密钥
*
* [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) 密钥
*/
public static byte[] key() {
byte[] key = new byte[KEY_BIT_SIZE / 8];
SECURE_RANDOM.nextBytes(key);
return key;
}
/**
* 创建向量
*
* [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) 向量
*/
public static byte[] iv() {
byte[] iv = new byte[NONCE_BIT_SIZE / 8];
SECURE_RANDOM.nextBytes(iv);
return iv;
}
/**
* 编码
*
* @param hexStr 文本
* [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) 字节数组
*/
public static byte[] hexToByte(String hexStr) {
int len = hexStr.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexStr.charAt(i), 16)<< 4)+ Character.digit(hexStr.charAt(i + 1), 16));
}
return data;
}
/**
* 转为十六进制
*
* @param data 字节数组
* [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) 转换结果
*/
public static String toHex(byte[] data) {
StringBuilder ret = new StringBuilder();
for (byte datum : data) {
String hex = Integer.toHexString(datum & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
ret.append(hex.toUpperCase());
}
return ret.toString();
}
/**
* 加密
* @param plainText 明文文本
* @param key 密钥双重预防机制接口技术文档
* @param iv 向量
* [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) 加密字符串
*/
public static String encrypt(String plainText, byte[] key, byte[] iv) {
String sr;
try {
byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8);
GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
AEADParameters parameters =new AEADParameters(new KeyParameter(key),MAC_BIT_SIZE, iv, null);
cipher.init(true, parameters);
byte[] encryptedBytes = new
byte[cipher.getOutputSize(plainBytes.length)];
int retLen = cipher.processBytes(plainBytes, 0, plainBytes.length,
encryptedBytes, 0);
cipher.doFinal(encryptedBytes, retLen);
sr = Base64.getEncoder().encodeToString(encryptedBytes);
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
return sr;
}
/**
* 解密
* @param encryptedText 已加密文本
* @param key 密钥
* @param iv 向量
* [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) 已解密文本
*/
public static String decrypt(String encryptedText, byte[] key, byte[] iv) {
String sr;
try {
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
AEADParameters parameters =new AEADParameters(new KeyParameter(key),MAC_BIT_SIZE, iv, null);
cipher.init(false, parameters);
byte[] plainBytes = new
byte[cipher.getOutputSize(encryptedBytes.length)];
int retLen = cipher.processBytes
(encryptedBytes, 0, encryptedBytes.length, plainBytes, 0);
cipher.doFinal(plainBytes, retLen);
sr = new String(plainBytes, StandardCharsets.UTF_8);
} catch (IllegalArgumentException | IllegalStateException |
DataLengthException | InvalidCipherTextException ex) {
throw new RuntimeException(ex.getMessage());
}
return sr;
}
}
maven 的引用见下:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.56</version>
</dependency>
String encryptedStr = AesGcm256Util.encrypt(originData,
AesGcm256Util.hexToByte(AES_KEY),
AesGcm256Util.hexToByte(AES_IV));
String resultStr = AesGcm256Util.decrypt(encryptedStr,
AesGcm256Util.hexToByte(AES_KEY),
AesGcm256Util.hexToByte(AES_IV));
上面是三方文档提供的java代码示例,由于本人不懂java不知道如何转成php的代码,网上百度了很多方法都跟他的结果不一致- -
下面是key iv 和我的内容
$aes_key = '84702E415A73CE27077B5F726E7BDBB0';
$aes_iv = '1C7AA98593AA69F4AAE119BD5C01D9ED';
$param = '{\"parameter\":{\"pid\":\"6958\"}}';
java加密出来的正确字符串为:
p7EA1l1eCbtDx/6PAvrlHW7NAez0IDJaY64jM503Q4HDLTB9KvoYIF3Hnl4=
这是我php的方法,我不太清楚key和iv是否需要做处理,我暂时没处理,求看的懂的大佬指导一二!
下面是转为二进制之后的结果好像还是不一样
经过有个qq群大佬指导终于知道怎么回事了!三方文档标题写的256加密实际代码是128!!!真是恶心,问他们不回复
最后代码如下 需要将加密完的encode和tag拼接base64_encode才可以!
$cipher = "AES-128-GCM";
$key = '84702E415A73CE27077B5F726E7BDBB0';
$key = hex2bin($key);
$iv = '1C7AA98593AA69F4AAE119BD5C01D9ED';
$iv = hex2bin($iv);
$packString = "{\"parameter\":{\"pid\":\"6958\"}}";
$encode = openssl_encrypt($packString, $cipher, $key, OPENSSL_NO_PADDING, $iv, $tag);
var_dump([base64_encode($encode), base64_encode($tag)]);
推荐文章: