使用 openssl_public_decrypt 解密签名
Decrypt a signature using openssl_public_decrypt
我正在尝试验证对我们端点之一的外部调用,此端点由第三方触发,我们收到交易数据和基于该交易信息的签名,我们需要解密签名并比对结果以验证真伪。
我正在尝试使用 openssl_public_decrypt
通过提供商的 public 密钥解密签名。
这就是我正在尝试的方式:
$signature = 'GcTtinhU0YgwGbZPtBwLdh+zdEe0w0W95TFPggeHMCjeDUBWgZfCZ6ZDRUk7DfT5BkKsbAi8/4o60Krcwz1JMdRjmsPf7vj33heVIB2PZJaf8eFR1jijLIsyl4vgH7BbbQ2I6kk6IcYXYWPVAHYRWxl1pJwOyNxZPr49fdW+hcw2zbpkEmj2114QBSiV6eHLowVYKLvpuiT8zLc6DN/wVzCYBuR/cg+CPHgYMeWFsuvu9J46hm6Hij00E68ldYAqVwImlmHPqfqvdEItg3Oi0ac4tXH2nCNgLPHcyU/H32NzTYC9iT1YZkoInqsU6Qv64vbU9lSMS91EQBEa5UQkUg==';
$pubKey = openssl_pkey_get_public('file://path/to/public.pem');
if( openssl_public_decrypt(base64_decode($signature), $data, $pubKey)){
echo $data;
}else{
echo 'Error';
}
我没有收到任何错误,但是 $data
值不是我所期望的,是这样的
v_~�@&�W��q�&Ș�uQ���֔�
我确定我遗漏了什么,但我找不到它是什么,因为 $data
值看起来是加密的。
我期望解密的结果是167619085f7ed94026e357930b18dc011971f226c898ef7551cdf6ec9ad694cf
这是以下代码的结果
$canonical = 'c328e942-8be8-4104-abbe-048254f893dc|9687|2874.30|52409|BP1381|550bd8439cd1f41691671cdd4e8c6ae6';
$hashed = hash('sha256', $canonical);
最后一部分是提供商如何生成签名。
For the given example, canonic form is as follows:
cec4b9bf-5a39-4bd7-bc8b826ebc18208d|Internal_0005|12|39679|BP7610|947d589a40dece13c28f2b63c41ae451
We sign the response by hashing the canonic form with SHA-256 and encrypting the
resulting bytes with our private key.
RSA_ENCRYPT(SHA256(canonicForm), privkey.key)
To verify the payload, you must recalculate the canonic form and apply SHA-256 to the
result. The resulting value must be compared with the result of decrypting the signature
parameter with our public key.
如有任何提示,我们将不胜感激。
也许 post public 密钥和一些有效的测试数据,以便我们可以测试自己?
无论如何,v_~�@&�W��q�&Ș�uQ���֔�
可能是一个有效的签名,记住 SHA256 是 256 个随机位,它是二进制数据,不是 ascii 数据,不是十六进制,也不可打印。 SHA256也恰好是32字节长(256位,1字节就是8位,256/8就是32字节),所以如果你运行var_dump(strlen($data))解密后,它 应该 打印 32,如果它不打印 32,则意味着他们正在使用填充方案,请尝试检查 OPENSSL_PKCS1_PADDING 和 OPENSSL_NO_PADDING 的 strlen,当你得到正确的填充方案时,解密后的 strlen($data) 应该是 int(32)
但我最好的猜测是:
$signature = 'GcTtinhU0YgwGbZPtBwLdh+zdEe0w0W95TFPggeHMCjeDUBWgZfCZ6ZDRUk7DfT5BkKsbAi8/4o60Krcwz1JMdRjmsPf7vj33heVIB2PZJaf8eFR1jijLIsyl4vgH7BbbQ2I6kk6IcYXYWPVAHYRWxl1pJwOyNxZPr49fdW+hcw2zbpkEmj2114QBSiV6eHLowVYKLvpuiT8zLc6DN/wVzCYBuR/cg+CPHgYMeWFsuvu9J46hm6Hij00E68ldYAqVwImlmHPqfqvdEItg3Oi0ac4tXH2nCNgLPHcyU/H32NzTYC9iT1YZkoInqsU6Qv64vbU9lSMS91EQBEa5UQkUg==';
$canonical = 'c328e942-8be8-4104-abbe-048254f893dc|9687|2874.30|52409|BP1381|550bd8439cd1f41691671cdd4e8c6ae6';
$pubKey = openssl_pkey_get_public('file://path/to/public.pem');
if( openssl_public_decrypt(base64_decode($signature), $data, $pubKey)){
echo "signature decryption success! ";
if(hash_equals(hash("sha256",$canonical,true),$data)){
echo "checksum verification success!";
} else{
echo "checksum verification failed (after decryption was successful..)";
}
}else{
echo 'checksum decryption error';
}
但再次尝试两者
if( openssl_public_decrypt(base64_decode($signature), $data, $pubKey, OPENSSL_PKCS1_PADDING)){
和
if( openssl_public_decrypt(base64_decode($signature), $data, $pubKey, OPENSSL_NO_PADDING)){
其中 1 个可能是正确的(如果正确,var_dump(strlen($data)) 应该打印 int(32) )
我正在尝试验证对我们端点之一的外部调用,此端点由第三方触发,我们收到交易数据和基于该交易信息的签名,我们需要解密签名并比对结果以验证真伪。
我正在尝试使用 openssl_public_decrypt
通过提供商的 public 密钥解密签名。
这就是我正在尝试的方式:
$signature = 'GcTtinhU0YgwGbZPtBwLdh+zdEe0w0W95TFPggeHMCjeDUBWgZfCZ6ZDRUk7DfT5BkKsbAi8/4o60Krcwz1JMdRjmsPf7vj33heVIB2PZJaf8eFR1jijLIsyl4vgH7BbbQ2I6kk6IcYXYWPVAHYRWxl1pJwOyNxZPr49fdW+hcw2zbpkEmj2114QBSiV6eHLowVYKLvpuiT8zLc6DN/wVzCYBuR/cg+CPHgYMeWFsuvu9J46hm6Hij00E68ldYAqVwImlmHPqfqvdEItg3Oi0ac4tXH2nCNgLPHcyU/H32NzTYC9iT1YZkoInqsU6Qv64vbU9lSMS91EQBEa5UQkUg==';
$pubKey = openssl_pkey_get_public('file://path/to/public.pem');
if( openssl_public_decrypt(base64_decode($signature), $data, $pubKey)){
echo $data;
}else{
echo 'Error';
}
我没有收到任何错误,但是 $data
值不是我所期望的,是这样的
v_~�@&�W��q�&Ș�uQ���֔�
我确定我遗漏了什么,但我找不到它是什么,因为 $data
值看起来是加密的。
我期望解密的结果是167619085f7ed94026e357930b18dc011971f226c898ef7551cdf6ec9ad694cf
这是以下代码的结果
$canonical = 'c328e942-8be8-4104-abbe-048254f893dc|9687|2874.30|52409|BP1381|550bd8439cd1f41691671cdd4e8c6ae6';
$hashed = hash('sha256', $canonical);
最后一部分是提供商如何生成签名。
For the given example, canonic form is as follows: cec4b9bf-5a39-4bd7-bc8b826ebc18208d|Internal_0005|12|39679|BP7610|947d589a40dece13c28f2b63c41ae451
We sign the response by hashing the canonic form with SHA-256 and encrypting the resulting bytes with our private key.
RSA_ENCRYPT(SHA256(canonicForm), privkey.key)
To verify the payload, you must recalculate the canonic form and apply SHA-256 to the result. The resulting value must be compared with the result of decrypting the signature parameter with our public key.
如有任何提示,我们将不胜感激。
也许 post public 密钥和一些有效的测试数据,以便我们可以测试自己?
无论如何,v_~�@&�W��q�&Ș�uQ���֔�
可能是一个有效的签名,记住 SHA256 是 256 个随机位,它是二进制数据,不是 ascii 数据,不是十六进制,也不可打印。 SHA256也恰好是32字节长(256位,1字节就是8位,256/8就是32字节),所以如果你运行var_dump(strlen($data))解密后,它 应该 打印 32,如果它不打印 32,则意味着他们正在使用填充方案,请尝试检查 OPENSSL_PKCS1_PADDING 和 OPENSSL_NO_PADDING 的 strlen,当你得到正确的填充方案时,解密后的 strlen($data) 应该是 int(32)
但我最好的猜测是:
$signature = 'GcTtinhU0YgwGbZPtBwLdh+zdEe0w0W95TFPggeHMCjeDUBWgZfCZ6ZDRUk7DfT5BkKsbAi8/4o60Krcwz1JMdRjmsPf7vj33heVIB2PZJaf8eFR1jijLIsyl4vgH7BbbQ2I6kk6IcYXYWPVAHYRWxl1pJwOyNxZPr49fdW+hcw2zbpkEmj2114QBSiV6eHLowVYKLvpuiT8zLc6DN/wVzCYBuR/cg+CPHgYMeWFsuvu9J46hm6Hij00E68ldYAqVwImlmHPqfqvdEItg3Oi0ac4tXH2nCNgLPHcyU/H32NzTYC9iT1YZkoInqsU6Qv64vbU9lSMS91EQBEa5UQkUg==';
$canonical = 'c328e942-8be8-4104-abbe-048254f893dc|9687|2874.30|52409|BP1381|550bd8439cd1f41691671cdd4e8c6ae6';
$pubKey = openssl_pkey_get_public('file://path/to/public.pem');
if( openssl_public_decrypt(base64_decode($signature), $data, $pubKey)){
echo "signature decryption success! ";
if(hash_equals(hash("sha256",$canonical,true),$data)){
echo "checksum verification success!";
} else{
echo "checksum verification failed (after decryption was successful..)";
}
}else{
echo 'checksum decryption error';
}
但再次尝试两者
if( openssl_public_decrypt(base64_decode($signature), $data, $pubKey, OPENSSL_PKCS1_PADDING)){
和
if( openssl_public_decrypt(base64_decode($signature), $data, $pubKey, OPENSSL_NO_PADDING)){
其中 1 个可能是正确的(如果正确,var_dump(strlen($data)) 应该打印 int(32) )