示例签名php

时间:2013-03-01 01:55:55

标签: php encryption signature

我实现了一个示例(为了更好地理解我自己)数字签名的工作方式(在我的情况下使用php)。

我使用Bob和Alice的故事“如何使用数字签名进行身份验证?”来自http://www.verisign.com.au/repository/tutorial/digital/intro1.shtml

“假设Alice想要向Bob发送签名消息。她通过在消息上使用散列函数创建消息摘要。消息摘要用作消息的”数字指纹“;如果任何部分消息被修改后,哈希函数返回不同的结果。然后,Alice用她的私钥加密消息摘要。这个加密的消息摘要是消息的数字签名。 Alice将消息和数字签名都发送给Bob。当Bob收到它们时,他使用Alice的公钥解密签名,从而揭示消息摘要。为了验证该消息,他然后使用Alice使用的相同散列函数对消息进行散列,并将结果与​​他从Alice收到的消息摘要进行比较。如果它们完全相同,那么Bob可以确信该消息确实来自Alice并且自签署以来没有改变。如果消息摘要不相等,则消息来自其他地方或在签名后被更改(或私钥不同)。“

在发布代码之前,我想提一下,这可能不是使用标准生成密钥的正确方法。但是我应该(也许你)了解签名的工作原理。

echo "Example 2 <br><br>";

$res = openssl_pkey_new();

/* Extract the private key from $res to $privKey */
openssl_pkey_export($res, $privKey);

/* Extract the public key from $res to $pubKey */
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];

$message = "Im a message";

echo "<br><br><strong>Public key:</strong><br>";
echo $pubKey;
echo "<br><br><strong>Private key:</strong><br>";
echo $privKey;

echo "<br><br><strong>Message:</strong><br>";
echo $message;

echo "<br><br><strong>Message digest:</strong><br>";
echo $md5message = sha1($message);

echo "<br><br><strong>Message digest encrypted(signature):</strong><br>";
openssl_private_encrypt($md5message, $crypted, $privKey);
echo $crypted;

echo "<br><br><strong>Bob uses sha1 as well for the message:</strong><br>";
echo $md5message = md5($message);

echo "<br><br><strong>Bob checks with decrypt(verify):</strong><br>";
openssl_public_decrypt($crypted, $decrypted, $pubKey);
echo $decrypted;

我有3个问题:

1)工作流程是否适用于签名的工作方式?我应该改变什么(如前所述,我不想生成“正确的”.pem,.crt等密钥......对我来说将是下一步。)

2)据我所知,私钥总是要解密。加密的公钥。我知道这里的措辞是私钥的标志,并用公钥验证。显然,我只能使用公钥在此示例中验证它。我无法理解这一点。这怎么可能?也许你可以给我一个更好的例子或链接?

3)我的实施应该改变什么?

提前致谢。

1 个答案:

答案 0 :(得分:1)

好的,我会发表一些评论。

  1. 关于Alice和Bob的文字似乎是正确的,尽管最后一句“如果消息摘要不相等,则该消息要么在其他地方发起,要么在签名后被更改”。显然可以使用“或使用其他私钥签名的邮件”进行扩展。

  2. 工作流程是正确的,虽然openssl_private_encrypt有点太高,无法显示实际发生的情况。它可能会执行填充以进行签名生成,但不对所使用的哈希算法的OID进行编码(请参阅相当可读的PKCS#1规范以查看我正在谈论的内容)。因此,在这种意义上,您的签名方案不太可能与其他任何内容进行验证。

  3. 很明显,验证部分缺少实际验证,您需要将生成的散列与您在本地计算的散列进行比较。此外,你永远不应该使用MD5。可能你应该使用PSS填充方案而不是旧的PKCS#1 v1.5兼容方案。