我正在努力更好地了解公钥/私钥是如何工作的。我知道发送方可以使用他/她的私钥向文档添加数字签名,从而实质上获得文档的哈希值,但我不理解的是如何使用公钥来验证该签名。

我的理解是公钥加密,私钥解密…有人能帮我理解一下吗?


当前回答

下面是一个使用Python验证公钥签名的示例

您需要安装pycryptodome。从这里开始

# pip install pycryptodome

from Crypto.PublicKey import RSA
from hashlib import sha512

# create RSA key-pair
keyPair = RSA.generate(bits=1024)
public_key = (keyPair.e, keyPair.n)
private_key = (keyPair.d, keyPair.n)

msg = b'A message for signing'
hash = int.from_bytes(sha512(msg).digest(), byteorder='big')

# RSA sign the message using private key
signature = pow(hash, private_key[0], private_key[1])

# RSA verify signature using public key
hashFromSignature = pow(signature, public_key[0], public_key[1])
print("Signature valid:", hash == hashFromSignature)

其他回答

公钥加密,只有私钥可以解密,反之亦然。它们都加密为不同的哈希值,但每个密钥都可以解密对方的加密。

有几种不同的方法可以验证消息是否来自预期的发送方。例如:

发件人发送:

的消息 用他们的私钥加密的消息的哈希值

接收方:

用公钥解密签名(2)以获得一条消息,该消息应该与(1)相同,但我们还不知道。现在我们有两个消息,我们需要验证它们是否相同。为此,我们将用我们的公钥对它们进行加密,并比较两个哈希值。所以我们将.... 用公钥加密原始消息(1)以获得哈希值 加密解密的消息(3)以获得第二个散列,并与(4)进行比较以验证它们是否相同。

如果它们不相同,这意味着要么消息被篡改了,要么它是用其他密钥签名的,而不是我们认为的那个……

另一个例子是发送方使用接收方可能也知道使用的公共散列。例如:

发件人发送:

一个消息 获取消息的已知哈希值,然后使用私钥加密该哈希值

接收方:

解密(2)并获得一个哈希值 使用发送方使用的相同散列对消息(1)进行散列 比较两个散列以确保它们匹配

这再次确保消息没有被篡改,并且它来自预期的发送者。

我认为误解中的最大问题是,当人们读到“不对称”这个词时,在他们的头脑中,他们认为“好吧,一个密钥加密,另一个密钥解密,因此它们是不对称的”。但如果你理解不对称实际上意味着“if密钥A加密了数据,那么它的“姐妹”密钥B可以解密数据。如果密钥B被用来加密数据,那么密钥A现在只能解密。”对称意味着用于加密数据的相同密钥可以用于解密数据。

关于你的问题,我在看RSA的实现。并且更清楚地了解了使用公钥验证使用私钥的签名的方式。毫无疑问,私钥不会被暴露。以下是如何……

这里的技巧是将私钥隐藏在函数中。这里是(p-1)*(q-1)

假设p是私钥,e是公钥。P被封装在另一个函数中以使其隐藏。

E.g., `d = (p-1)(q-1); d * e = 1` (d is the inverse of e - public key)
Data sent = [encrypted(hash), message] = [m ^d, message];

留言在哪里 假设

'Data sent' = y

为了检验完整性,我们找到y^e得到m,因为m ^(d*e) = m ^1 = m。

希望这能有所帮助!:)

下面是一个使用Python验证公钥签名的示例

您需要安装pycryptodome。从这里开始

# pip install pycryptodome

from Crypto.PublicKey import RSA
from hashlib import sha512

# create RSA key-pair
keyPair = RSA.generate(bits=1024)
public_key = (keyPair.e, keyPair.n)
private_key = (keyPair.d, keyPair.n)

msg = b'A message for signing'
hash = int.from_bytes(sha512(msg).digest(), byteorder='big')

# RSA sign the message using private key
signature = pow(hash, private_key[0], private_key[1])

# RSA verify signature using public key
hashFromSignature = pow(signature, public_key[0], public_key[1])
print("Signature valid:", hash == hashFromSignature)

我想为那些寻找更直观的东西的人提供一个补充解释。

这种困惑的很大一部分来自于命名“公钥”和“私钥”,因为这些东西的实际工作方式与“密钥”的理解方式直接不一致。

以加密为例。它可以被认为是这样工作的:

希望能够阅读秘密消息的各方都拥有一把密钥 隐藏(即私钥) 希望能够发送秘密消息的各方都有能力获得一个未解锁的锁(即一个公共锁) 然后发送秘密信息就像用一把没有上锁的锁一样简单,但之后只能用其中一把隐藏的钥匙来解锁。

这允许秘密消息在各方之间发送,但从直观的角度来看,“公共锁”是一个比“公钥”更合适的名称。

然而,对于发送数字签名,角色有点相反:

The party that wants to sign messages is the only one with access to the unlocked locks (i.e. a private lock) The parties that want to verify the signature all have the ability to obtain a key (i.e. a public key) Then what the signer does is create two identical messages: the one that anyone can read and one to accompany it, but which they lock with one of their private locks. Then when the receiver gets the message, they can read it, and then use the public key to unlock the locked message and compare the two messages. If the messages are the same, then they know that: The unlocked message wasn't tampered with during travel and, The message must have been from the person who has the matching lock to their public key. And finally, this entire system only works if anyone who wants to validate a signer's signature has an authoritative place to go to to get the matching key to the signer's locks. Otherwise, anyone can say "Hey, here's the key to so-and-so's private lock", send you a message pretending to be them but lock it with their private lock, you perform all the above steps and believe the message must actually be from the person you thought, but you're fooled because you were mislead as to the true owner of a public key.

只要有一个可信赖的来源来检索签名者的公钥,您就会知道公钥的合法所有者是谁,并能够验证他们的签名。