PHP公钥加密API令牌异常:每次加密结果不一致
问题解答
1. 每次加密结果不同是否正常?
正常。RSA公钥加密默认使用随机填充算法(比如PKCS#1 v1.5或OAEP),每次加密时会生成不同的随机填充值,因此即使明文相同,加密后的密文也会不一样。这是RSA加密的安全特性,不属于异常情况。
2. API返回加密错误的原因及修复方案
你的代码存在两个关键问题,导致生成的令牌不符合API要求:
问题一:时间戳处理错误
API要求的challenge.getTime是毫秒级时间戳,但你用strtotime($challenge)得到的是秒级时间戳,丢失了原时间字符串中的.166毫秒部分,直接导致加密的明文与API预期不一致。
问题二:公钥重复处理无效
你已经通过openssl_pkey_get_public($public_key)获取了有效的公钥资源$pkey_public,后续调用openssl_csr_get_public_key($public_key)完全多余——这个函数是用来从证书签名请求(CSR)中提取公钥,不是处理已有的公钥字符串,这一步可能导致公钥资源异常。
修正后的代码
// 加载公钥文件 $fopen_public = fopen("publicKey.pem", "r"); $public_key_content = fread($fopen_public, 8192); fclose($fopen_public); // 解析公钥为可用资源 $pkey_public = openssl_pkey_get_public($public_key_content); if (!$pkey_public) { die("公钥加载失败,请检查文件格式"); } $token = 'contents of the token'; $challenge = "2022-12-22T08:51:41.166Z"; // 转换为API要求的毫秒级时间戳 $dt = new DateTime($challenge); $timestamp_ms = $dt->getTimestamp() * 1000 + (int)$dt->format('u') / 1000; // 拼接需要加密的明文 $data = $token . '|' . $timestamp_ms; // 执行公钥加密 $encrypted_data = ''; $encrypt_success = openssl_public_encrypt($data, $encrypted_data, $pkey_public); if (!$encrypt_success) { die("加密操作失败,请检查公钥或明文格式"); } // 转为Base64编码 $encrypted_data = base64_encode($encrypted_data); // 调试输出 echo $data."<br>".$timestamp_ms."<br>".$encrypted_data."<br><br>".$challenge."<br>".$timestamp_ms;
额外注意事项
- 如果API明确指定了加密填充方式(比如OAEP),需要在
openssl_public_encrypt中添加第四个参数,例如:openssl_public_encrypt($data, $encrypted_data, $pkey_public, OPENSSL_PKCS1_OAEP_PADDING) - 确保
publicKey.pem是标准的PEM格式公钥,无格式错误或内容缺失
内容的提问来源于stack exchange,提问作者Konrad
相关产品推荐
相关产品推荐

