需求背景:在做游戏防沉迷操作中,需要先做前置的接口验证过程,在文档中示例中,给出的是java代码
-
/**
-
* <p>@title aesGcmEncrypt</p>
-
* <p>@description Aes-Gcm加密</p>
-
*
-
* @param content 待加密文本
-
* @param key 密钥
-
* @return java.lang.String
-
*/
-
private static String aesGcmEncrypt(String content, byte[] key) {
-
try {
-
// 根据指定算法ALGORITHM自成密码器
-
Cipher cipher = Cipher.getInstance(
"AES/GCM/PKCS5Padding");
-
SecretKeySpec skey =
new SecretKeySpec(key,
"AES");
-
cipher.init(Cipher.ENCRYPT_MODE, skey);
-
//获取向量
-
byte[] ivb = cipher.getIV();
-
byte[] encodedByteArray = cipher.doFinal(content.getBytes(UTF_8));
-
byte[] message =
new
byte[ivb.length + encodedByteArray.length];
-
System.arraycopy(ivb,
0, message,
0, ivb.length);
-
System.arraycopy(encodedByteArray,
0, message, ivb.length, encodedByteArray.length);
-
return Base64.getEncoder().encodeToString(message);
-
}
catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException
-
| BadPaddingException e) {
-
//建议自行调整为日志输出或抛出异常
-
return
null;
-
}
-
}
-
-
/**
-
* <p>@title aesGcmDecrypt</p>
-
* <p>@description Aes-Gcm解密</p>
-
*
-
* @param content 带解密文本
-
* @param key 密钥
-
* @return java.lang.String
-
*/
-
private static String aesGcmDecrypt(String content, byte[] key) {
-
try {
-
// 根据指定算法ALGORITHM自成密码器
-
Cipher decryptCipher = Cipher.getInstance(
"AES/GCM/NoPadding");
-
SecretKeySpec skey =
new SecretKeySpec(key,
"AES");
-
byte[] encodedArrayWithIv = Base64.getDecoder().decode(content);
-
GCMParameterSpec decryptSpec =
new GCMParameterSpec(
128, encodedArrayWithIv,
0,
12);
-
decryptCipher.init(Cipher.DECRYPT_MODE, skey, decryptSpec);
-
byte[] b = decryptCipher.doFinal(encodedArrayWithIv,
12, encodedArrayWithIv.length -
12);
-
return
new String(b, UTF_8);
-
}
catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException
-
| BadPaddingException | InvalidAlgorithmParameterException e) {
-
//建议自行调整为日志输出或抛出异常
-
return
null;
-
}
-
}
本人不是很懂java所以这个代码也是看的云里雾里的,然后我就用PHP的 openssl_encrypt()方法做了相同的加密方式(本方法支持PHP7.1+)
如下
-
private
function aesGcm($data)
-
{
-
-
$key =
self::SECRETKEY;
-
-
$cipher =
"aes-128-gcm";
-
$ivlen = openssl_cipher_iv_length($cipher);
-
$iv = openssl_random_pseudo_bytes($ivlen);
-
$encrypt = openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA,$iv,$tag);
-
return base64_encode(($iv.$encrypt.$tag));
-
}
然后测试网站一直提示测试无法通过。
通过一系列操作终于发现 需要将$key转成ASC||。
最后的代码PHP代码段:
-
private
function aesGcm($data)
-
{
-
-
$key =
self::SECRETKEY;
-
$key = hex2bin($key);
-
$cipher =
"aes-128-gcm";
-
$ivlen = openssl_cipher_iv_length($cipher);
-
$iv = openssl_random_pseudo_bytes($ivlen);
-
$encrypt = openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA,$iv,$tag);
-
return base64_encode(($iv.$encrypt.$tag));
-
}
PHP7.1以下的请参考 :https://github.com/Spomky-Labs/php-aes-gcm
-
public
function aesGcmEncrypt($string)
-
{
-
$cipher = strtolower(
'AES-128-GCM');
-
if(is_array($string)) $string = json_encode($string);
-
//二进制key
-
$skey = hex2bin(
$this->secretKey);
-
//二进制iv
-
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
-
require APPPATH .
'vendor/autoload.php';
-
list($content, $tag) = AESGCM::encrypt($skey, $iv, $string);
-
//如果环境是php7.1+,直接使用下面的方式
-
// $tag = NULL;
-
// $content = openssl_encrypt($string, $cipher, $skey,OPENSSL_RAW_DATA,$iv,$tag);
-
$str = bin2hex($iv) . bin2hex($content) . bin2hex($tag);
-
return base64_encode(hex2bin($str));
-
}
如有不懂 请加QQ群一起讨论 :789235512
转载:https://blog.csdn.net/qq_39370482/article/details/113727328
查看评论