简体   繁体   English

如何在 python 上使用 RSA 私钥和 SHA256 进行解密

[英]How to use decrypt with RSA private key and SHA256 on python

I am learning for school to encrypt and decrypt a file using public and private keys en encoding.我正在为学校学习使用公钥和私钥编码来加密和解密文件。

I used this code to encode the message.我使用此代码对消息进行编码。 (which generates public key ≠ not private key error) (产生公钥≠不是私钥错误)

from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA



def signing():
    #open file = message als binary
    message = open('C:/Users/Gebruiker/Desktop/message.txt', "rb").read()
    #open public key -> key     
    key = RSA.import_key(open('C:/Users/Gebruiker/Desktop/public.pem').read())
    #message becomes a hash
    h = SHA256.new(message)  
    #f = open file as write binary
    f = open('C:/Users/Gebruiker/Desktop/message.signature', 'wb')
    # sign hash message with private key  
    signature = pkcs1_15.new(key).sign(h) 
    #write signed hash to file 
    f.write(signature)
    f.close()

But now i am trying to decode this message and I found all these people that do it in different ways and work with different type of encoding and encrypting.但现在我正在尝试解码这条消息,我发现所有这些人都以不同的方式进行解码,并使用不同类型的编码和加密。 And I cant find a clear answer.而且我找不到明确的答案。

what i have right now is this我现在拥有的是这个

First i have to read the message so首先,我必须阅读消息

def decrypt():
    f = open('C:/Users/Gebruiker/Desktop/message.signature', 'rb').read()

then i open up my private key然后我打开我的私钥

    key = RSA.import_key(open('C:/Users/Gebruiker/Desktop/private.pem').read())

Because I write and read in binary i have to turn it back into a hash因为我用二进制读写我必须把它转回 hash

    h = SHA256.new(f)

And then i have to decrypt the hash using my private key.???然后我必须使用我的私钥解密 hash。???

Instead i see a lot of people using something like this.相反,我看到很多人使用这样的东西。

    h = pkcs1_15.new(key).sign(h)  # sign hash message with private key

which i don't get.我不明白。 You are supposed to decode it right?你应该解码它吧? not sign it again.不要再签了。 this part makes no sense to me.这部分对我来说毫无意义。

Now I have 2 problems.现在我有2个问题。

  1. I get an encoding error saying my public key is not a private key.我收到一个编码错误,说我的公钥不是私钥。 Which is kinda the point of public keying right.这有点像公钥加密的重点。 so only private key can decrypt?所以只有私钥可以解密? Why am i getting an error?为什么我会收到错误消息?
  2. I don't know how to proceed with the decrypting of my message我不知道如何继续解密我的消息

Can anybody help me with this?有人可以帮我吗?

Thanks a lot!非常感谢!

There is confusion in your question.你的问题有混淆。 Signature generation for RSA requires modular exponentiation using the values of the private key , not the public key. RSA 的签名生成需要使用private key的值进行模幂运算,而不是 public key。 Modular exponentiation is also used for encryption with the public key.模幂运算也用于使用公钥进行加密 But although the same mathematical formula is used - at least on the surface - doesn't mean that signature generation is encryption with the private key because such a thing does not exist .但是,尽管使用了相同的数学公式——至少在表面上——并不意味着签名生成是用私钥加密的,因为这样的事情不存在 Current PKCS#1 standards go out of their way to explain this fact, even though earlier PKCS#1 standards used to identify signature generation with RSA encryption.当前的 PKCS#1 标准 go 无法解释这一事实,尽管早期的PKCS#1 标准使用 RSA 加密来识别签名生成。

What you are trying to do is to verify the message.您要做的是验证消息。 That's the function you would expect rather than sign .那是您期望的 function 而不是sign Verification is performed by a trusted public key , not by a private key.验证由受信任的公钥执行,而不是由私钥执行。 You are not trying to decode the message, you are trying to verify that the bytes of the message are indeed signed by the private key that belongs to the same key pair as the trusted public key.您不是在尝试解码消息,而是在尝试验证消息的字节确实由与受信任的公钥属于同一密钥对的私钥签名。 Generally, the message is not recovered, not even partially.通常,消息不会被恢复,甚至不会部分恢复。 PKCS#1 is called signature generation with appendix, which contrasts with other schemes called signature generation giving message recovery . PKCS#1 被称为带有附录的签名生成,它与其他称为签名生成给出消息恢复的方案形成对比。 The appendix is the signature value , it needs to be appended (included with) the message to be of any use.附录是签名值,它需要附加(包含在)消息中才能使用。

Actually, the fact that you can at least recover the hash over the message is specific to some schemes like PKCS#1 signature generation (officially called RSASSA-PKCS1-v1_5 in the standard ).实际上,您至少可以通过消息恢复 hash 这一事实特定于某些方案,例如 PKCS#1 签名生成(在标准中正式称为RSASSA-PKCS1-v1_5 )。 Other schemes such as PSS in the same standard may not even recover the hash.同标准中的PSS等其他方案甚至可能无法恢复hash。 This is OK as long the verification (which can take place given the data and therefore hash) can succeed or fail.只要验证(可以在给定数据和散列的情况下进行)可以成功或失败,就可以了。 In other words, the verification should at least result in a boolean true / false, but it doesn't need to generate any other information.换句话说,验证至少应该导致 boolean 真/假,但不需要生成任何其他信息。

Or, in simplified pseudo-code:或者,在简化的伪代码中:

ciphertext = encrypt(publicKey, plaintext)
(recovered) plaintext = decrypt(privateKey, ciphertext)

and

signature = sign(privateKey, data)
verificationResult = verify(publicKey, data, signature)

where the data hashing algorithm is a configuration parameter for the signature generation & verification algorithm.其中数据哈希算法是签名生成和验证算法的配置参数 If you want to include it you could eg include it as initial parameter:如果您想包含它,您可以例如将其包含为初始参数:

signature = sign(SHA256alg, privateKey, data)
verificationResult = verify(SHA256alg, publicKey, data, signature)

Finally, you are talking about "decoding".最后,您在谈论“解码”。 You decode messages that have been encoded using an encoding scheme.您对使用编码方案编码的消息进行解码。 Encoding/decoding does not presume the presence of a key.编码/解码不假定密钥的存在。 We're talking about encryption / decryption and signature generation / verification instead.我们谈论的是加密/解密和签名生成/验证。 Examples of encoding are hexadecimals / base 64 that convert binary to text.编码的示例是将二进制转换为文本的十六进制/base 64。 Character encoding such as UTF-8 is about converting text to binary. UTF-8 等字符编码是将文本转换为二进制。

The convention is to encrypt with a receives public RSA key so that only the holder of the corresponding private key can decrypt the message.约定是使用接收到的公共 RSA 密钥进行加密,以便只有相应私钥的持有者才能解密消息。

Also by convention, you would use your private RSA key to create a signatur that everybody else with the corresponding public key can verify.同样按照惯例,您将使用您的私有 RSA 密钥来创建一个签名,其他拥有相应公钥的人都可以验证该签名。

In principle you could use a public key for creating a signature, but this would be an erroneous use case of the key, and is often prevented in the libraries implementing RSA.原则上,您可以使用公钥来创建签名,但这将是密钥的错误用例,并且通常在实现 RSA 的库中被阻止。 In your case you get a "public key ≠ not private key error" as you try to use a public key in a sign(..) call.在您的情况下,当您尝试在sign(..)调用中使用公钥时,您会收到"public key ≠ not private key error"

When signing you don't use the full message as input to RSA , but instead calculates a hash (you use SHA256).签名时,您不使用完整消息作为RSA的输入,而是计算 hash(您使用 SHA256)。 This hash would not need to be "decryped" in the signature verification, but instead recalculated on the original message, that you want to verify.这个 hash 不需要在签名验证中“解密”,而是在您想要验证的原始消息上重新计算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM