https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.htmlhttps://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.htmlhttps://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.html
我这里加密后,解密有时候成功,有时候返回false,有人知道怎么回事,问微信官方,官方也是一问三不知,搞了快一周还没解决这个问题。
//服务端api加密
public static function getRequestParam($url, $req)
{
$key = base64_decode(self::apiAES256['key']);
$sn = self::apiAES256['sn'];
$appId = self::miniAppID;
$time = time();
//16位随机字符
$nonce = rtrim(base64_encode(random_bytes(16)), '=');
$nonce = base64_encode(random_bytes(16));
$addReq = ["_n" => $nonce, "_appid" => $appId, "_timestamp" => $time];
$realReq = array_merge($addReq, $req);
ksort($realReq);
$realReq = json_encode($realReq);
//额外参数
$aad = $url . "|" . $appId . "|" . $time . "|" . $sn;
//12位随机字符
$iv = random_bytes(12);
//var_dump($iv);
$cipher = openssl_encrypt($realReq, "aes-256-gcm", $key, 1, $iv, $tag, $aad);
echo '<br>---------encrypt paras start-------------<br>';
echo '<pre>';
echo '$realReq:';
var_dump($realReq);
echo '$key:';
var_dump($key);
echo '$iv:';
var_dump(base64_encode($iv));
echo '$tag:';
var_dump(base64_encode($tag));
echo '$aad:';
var_dump($aad);
echo '<br>--------- encrypt paras end-------------<br>';
$iv = base64_encode($iv);
$data = base64_encode($cipher);
$authTag = base64_encode($tag);
$reqData = ["iv" => $iv, "data" => $data, "authtag" => $authTag];
//校验本地加密是否正确 非必须
//$checkParam = self::checkParam($key, $authTag, $iv, $data, $aad);
return ['ts' => $time, 'reqData' => json_encode($reqData)];
}
//服务端api签名,$newRe参数是经过服务端api加密后的请求参数
public static function sign(array $newRe, $url_path)
{
$time = $newRe['ts'];
$key = self::apiRSA256['private_key'];
$url = $url_path;
$appId = self::miniAppID;
$reqData = $newRe['reqData'];
$payload = "$url\n$appId\n$time\n$reqData";
$rsa = new RSA();
$rsa->loadKey($key);
$rsa->setHash("sha256");
$rsa->setMGFHash("sha256");
$signature = $rsa->sign($payload);
return base64_encode($signature);
}
//服务端验对api返回的加密的结果进行解密,得到真实返回
public static function jM($ts, $body, $url_path)
{
echo '<br>---------decrypt paras start-------------<br>';
echo '<pre>';
echo '$ts:';
var_dump($ts);
echo '$body:';
var_dump($body);
echo '$url_path:';
var_dump($url_path);
echo '<br>--------- decrypt paras end-------------<br>';
$url = $url_path;
$appId = self::miniAppID;;
$sn = self::apiAES256['sn'];
$aad = $url . '|' . $appId . '|' . $ts . '|' . $sn;
$key = self::apiAES256['key'];
$key = base64_decode($key);
$iv = base64_decode($body['iv']);
$data = $body['data'];
// if (strlen($data) % 16) {
// $data = str_pad($data,strlen($data) + 16 - strlen($data) % 16, "\0");
// }
$data = base64_decode($data);
$tag = base64_decode($body['authtag']);
//print_r($tag);
//print_r($data);
$result = openssl_decrypt($data, "aes-256-gcm", $key, 1, $iv, $tag, $aad);
var_dump( openssl_error_string());
var_dump($result);
if (!$result) {
print_r(openssl_error_string());
while ($msg = openssl_error_string())
{
echo "<br>ERROR: " . $msg;
}
}
//$result = \Qiniu\json_decode($result,true);
return $result;
}
头次见你这种echo方式的,你是在吐网页,还是在吐数据!
你的问题可能是由于在加密和解密过程中使用的随机生成的初始化向量(IV)或者认证标签(auth tag)不一致导致的。在你的代码中,你在加密和解密的过程中都使用了随机生成的 IV 和 auth tag,这可能会导致在解密过程中无法正确解密数据。
你需要确保在加密和解密过程中使用的 IV 和 auth tag 是一致的。你可以尝试将加密过程中生成的 IV 和 auth tag 保存下来,然后在解密过程中使用同样的 IV 和 auth tag。
另外,你的代码中在解密过程中使用了 base64 解码,但在加密过程中并没有对应的 base64 编码,这可能也会导致解密失败。你需要确保加密和解密过程中的编码和解码操作是一致的。
以下是一个简化的示例,展示了如何在加密和解密过程中使用相同的 IV 和 auth tag:
// 加密 $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-gcm')); $tag = ''; $ciphertext = openssl_encrypt($plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag); // 解密 $decrypted = openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);