简体   繁体   中英

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

    h = SHA256.new(f)

And then i have to decrypt the hash using my private key.???

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.

  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. 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.

What you are trying to do is to verify the message. That's the function you would expect rather than 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 . 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 ). Other schemes such as PSS in the same standard may not even recover the 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.

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. Character encoding such as UTF-8 is about converting text to binary.

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.

Also by convention, you would use your private RSA key to create a signatur that everybody else with the corresponding public key can verify.

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. In your case you get a "public key ≠ not private key error" as you try to use a public key in a sign(..) call.

When signing you don't use the full message as input to RSA , but instead calculates a hash (you use 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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