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是否需要做处理,我暂时没处理,求看的懂的大佬指导一二!
PHP  AES-GCM-256加密有java示例代码  但就是php加密的结果不对

下面是转为二进制之后的结果好像还是不一样

经过有个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)]);

PHP  AES-GCM-256加密有java示例代码  但就是php加密的结果不对

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

tag那个php为空,不是null字符

1周前 评论
AsaKa1 (楼主) 1周前
AsaKa1 (楼主) 1周前
deatil (作者) 1周前
AsaKa1 (楼主) 1周前
deatil (作者) 1周前
deatil (作者) 1周前
AsaKa1 (楼主) 1周前
讨论数量: 13

你好歹把 Java 的 原文、密钥、偏移量、密文 都发一下,不然怎么参照。

1周前 评论
AsaKa1 (楼主) 1周前

tag那个php为空,不是null字符

1周前 评论
AsaKa1 (楼主) 1周前
AsaKa1 (楼主) 1周前
deatil (作者) 1周前
AsaKa1 (楼主) 1周前
deatil (作者) 1周前
deatil (作者) 1周前
AsaKa1 (楼主) 1周前

我之前也遇到过,后面放弃 PHP 写了,用 JAVA 写个接口,PHP 去调

1周前 评论
AsaKa1 (楼主) 1周前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!