0

我实现了一个例子(为了更好地理解我自己)数字签名是如何工作的(在我的例子中是 php)。

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

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)我应该在我的实施中改变什么?

提前致谢。

4

1 回答 1

1

好的,我会发表一些意见。

  1. 关于 Alice 和 Bob 的文本似乎是正确的,尽管最后一句“如果消息摘要不相等,则消息要么源自其他地方,要么在签名后被更改”。显然可以用“或用不同的私钥签名的消息”来扩展。

  2. 工作流程是正确的,虽然openssl_private_encrypt有点太高了,无法显示真正发生的事情。它可能会为签名生成执行填充,但不会对所使用的散列算法的 OID 进行编码(请参阅相当易读的 PKCS#1 规范以了解我在说什么)。因此,从这个意义上说,您的签名方案不太可能与其他任何东西一起验证。

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

于 2013-03-02T15:37:28.207 回答