为什么签名和私钥加密的结果不同


why different result with sign and encrypt with priv key

我使用openssl进行编码,我想知道为什么openssl_sign函数在逻辑意义上给出了与openssl_private_encrypt不同的结果。

特别是openssl_sign:

$fp = fopen("i.pem", "r");  //i.pem is the private key file
$priv_key = fread($fp, 8192);
fclose($fp);
$pkeyid = openssl_get_privatekey($priv_key);
$data="f2e140eb-2b09-44ab-8504-87b25d81914c";
openssl_sign($data, $signature, $pkeyid);
$reto22 = base64_encode($signature);    //this gives UNmlEfwISea9hoGfiwdM.......

特别是使用openssl_private_encrypt:

$llave_priv = file_get_contents("i.pem");  //i.pem is the private key file
$plaintext = "f2e140eb-2b09-44ab-8504-87b25d81914c";
openssl_private_encrypt($plaintext, $encrypted, $llave_priv);
$reto = base64_encode($encrypted);  //this gives ugSMAsCQlIKIlQ17exIvSEqkA60.......

为什么reto22$reto不同?它们应该是一样的,不是吗?用priv key = sign加密,据我所知

感谢澄清mario

一般来说,公钥系统中的加密是用公钥进行的(这样私钥就可以用来解密),而签名是用私钥进行的(所以公钥就可以用来验证)

使用openssl的签名涉及对消息的哈希进行加密。因此,即使使用相同的密钥,输出也会有所不同,因为虽然openssl_private_encrypt确实像在签名方案中那样使用私钥进行加密,但它不会对消息进行散列,或者(可能不确定)执行与签名方案相同的填充。

坚持使用openssl_sign,因为与推出自己的签名方案相比,它将更高效,更不容易受到潜在的侧信道攻击。

看到这个答案:

https://stackoverflow.com/a/2706636/1359088

这很有帮助,因为它解释了openssl_sign在返回签名之前在内部对数据执行散列,而openssl_private_encrypt要求您自己执行散列。我从概念上理解为什么要使用openssl_sign(因为加密通常使用公钥完成,而签名则使用私钥),但我快疯了,因为SSCrypto有一个名为sign的方法,它返回的数据与openssl_private_encrypt而不是openssl_sign相同,上面的答案帮助我解决了这个问题。我正在iPhone应用程序中签名一条消息,该消息将由PHP验证;我使用SSCrypto进行签名,并使用openssl_verify进行验证,但我正在使用openssl_sign进行测试,因为我需要数据相同才能工作。

你可以用面粉做面包,也可以用面粉做成肉团。然而面包不是肉酱,肉酱也不是面包。

同样,加密不是签名,签名也不是加密。