我正在努力更好地了解公钥/私钥是如何工作的。我知道发送方可以使用他/她的私钥向文档添加数字签名,从而实质上获得文档的哈希值,但我不理解的是如何使用公钥来验证该签名。
我的理解是公钥加密,私钥解密…有人能帮我理解一下吗?
我正在努力更好地了解公钥/私钥是如何工作的。我知道发送方可以使用他/她的私钥向文档添加数字签名,从而实质上获得文档的哈希值,但我不理解的是如何使用公钥来验证该签名。
我的理解是公钥加密,私钥解密…有人能帮我理解一下吗?
当前回答
下面是一个使用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)进行散列 比较两个散列以确保它们匹配
这再次确保消息没有被篡改,并且它来自预期的发送者。
键的作用是相反的:
公钥加密,私钥解密(加密):
openssl rsautl -encrypt -inkey public.pem -pubin -in message.txt -out message.ssl
openssl rsautl -decrypt -inkey private.pem -in message.ssl -out message.txt
私钥加密,公钥解密(签名):
openssl rsautl -sign -inkey private.pem -in message.txt -out message.ssl
openssl rsautl -inkey public.pem -pubin -in message.ssl -out message.txt
下面是一个使用openssl测试整个流程的示例脚本。
#!/bin/sh
# Create message to be encrypted
echo "Creating message file"
echo "---------------------"
echo "My secret message" > message.txt
echo "done\n"
# Create asymmetric keypair
echo "Creating asymmetric key pair"
echo "----------------------------"
openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -out public.pem -pubout
echo "done\n"
# Encrypt with public & decrypt with private
echo "Public key encrypts and private key decrypts"
echo "--------------------------------------------"
openssl rsautl -encrypt -inkey public.pem -pubin -in message.txt -out message_enc_pub.ssl
openssl rsautl -decrypt -inkey private.pem -in message_enc_pub.ssl -out message_pub.txt
xxd message_enc_pub.ssl # Print the binary contents of the encrypted message
cat message_pub.txt # Print the decrypted message
echo "done\n"
# Encrypt with private & decrypt with public
echo "Private key encrypts and public key decrypts"
echo "--------------------------------------------"
openssl rsautl -sign -inkey private.pem -in message.txt -out message_enc_priv.ssl
openssl rsautl -inkey public.pem -pubin -in message_enc_priv.ssl -out message_priv.txt
xxd message_enc_priv.ssl
cat message_priv.txt
echo "done\n"
该脚本输出如下:
Creating message file
---------------------
done
Creating asymmetric key pair
----------------------------
Generating RSA private key, 1024 bit long modulus
...........++++++
....++++++
e is 65537 (0x10001)
writing RSA key
done
Public key encrypts and private key decrypts
--------------------------------------------
00000000: 31c0 f70d 7ed2 088d 9675 801c fb9b 4f95 1...~....u....O.
00000010: c936 8cd0 0cc4 9159 33c4 9625 d752 5b77 .6.....Y3..%.R[w
00000020: 5bfc 988d 19fe d790 b633 191f 50cf 1bf7 [........3..P...
00000030: 34c0 7788 efa2 4967 848f 99e2 a442 91b9 4.w...Ig.....B..
00000040: 5fc7 6c79 40ea d0bc 6cd4 3c9a 488e 9913 _.ly@...l.<.H...
00000050: 387f f7d6 b8e6 5eba 0771 371c c4f0 8c7f 8.....^..q7.....
00000060: 8c87 39a9 0c4c 22ab 13ed c117 c718 92e6 ..9..L".........
00000070: 3d5b 8534 7187 cc2d 2f94 0743 1fcb d890 =[.4q..-/..C....
My secret message
done
Private key encrypts and public key decrypts
--------------------------------------------
00000000: 6955 cdd0 66e4 3696 76e1 a328 ac67 4ca3 iU..f.6.v..(.gL.
00000010: d6bb 5896 b6fe 68f1 55f1 437a 831c fee9 ..X...h.U.Cz....
00000020: 133a a7e9 005b 3fc5 88f7 5210 cdbb 2cba .:...[?...R...,.
00000030: 29f1 d52d 3131 a88b 78e5 333e 90cf 3531 )..-11..x.3>..51
00000040: 08c3 3df8 b76e 41f2 a84a c7fb 0c5b c3b2 ..=..nA..J...[..
00000050: 9d3b ed4a b6ad 89bc 9ebc 9154 da48 6f2d .;.J.......T.Ho-
00000060: 5d8e b686 635f b6a4 8774 a621 5558 7172 ]...c_...t.!UXqr
00000070: fbd3 0c35 df0f 6a16 aa84 f5da 5d5e 5336 ...5..j.....]^S6
My secret message
done
下面是一个使用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)
关于你的问题,我在看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。
希望这能有所帮助!:)
您对“公钥加密,私钥解密”的理解是正确的…用于数据/消息加密。对于数字签名,情况正好相反。使用数字签名,您将试图证明由您签署的文件来自您。要做到这一点,您需要使用只有您拥有的东西:您的私钥。
简单来说,数字签名是数据(文件、消息等)的哈希值(SHA1、MD5等),随后使用签名者的私钥进行加密。因为这是只有签名者拥有(或应该拥有)的东西,所以这就是信任的来源。每个人都有(或应该有)访问签名者的公钥的权限。
为了验证数字签名,接收者
计算相同数据(文件、消息等)的哈希值, 使用发送方的公钥解密数字签名 比较两个哈希值。
如果匹配,则认为签名有效。如果它们不匹配,则意味着使用了不同的密钥对其进行签名,或者数据已被更改(有意或无意)。