简体   繁体   中英

Separate files for rsa encryption and decryption

So I am trying to make two programs, one to encode a message using rsa encryption, and one to decode it. In the encryption file I have:

import rsa


def generateKeys():
    (publicKey, privateKey) = rsa.newkeys(1024)
    with open('keys/publicKey.pem', 'wb') as p:
        p.write(publicKey.save_pkcs1('PEM'))
    with open('keys/privateKey.pem', 'wb') as p:
        p.write(privateKey.save_pkcs1('PEM'))


def loadKeys():
    with open('keys/publicKey.pem', 'rb') as p:
        publicKey = rsa.PublicKey.load_pkcs1(p.read())
    with open('keys/privateKey.pem', 'rb') as p:
        privateKey = rsa.PrivateKey.load_pkcs1(p.read())
    return privateKey, publicKey


def encrypt(message, key):
    return rsa.encrypt(message.encode('ascii'), key)


def sign(message, key):
    return rsa.sign(message.encode('ascii'), key, 'SHA-1')


#generateKeys()
privateKey, publicKey = loadKeys()
print(f"public key: {publicKey}, private key: {privateKey}")
encryptme = input('Write your message here:')
ciphertext = encrypt(encryptme, publicKey)
signature = sign(encryptme, privateKey)

print(str(ciphertext))
#print(signature)

and in the decryption file I have:

import rsa


def loadKeys():
    with open('keys/publicKey.pem', 'rb') as p:
        publicKey = rsa.PublicKey.load_pkcs1(p.read())
    with open('keys/privateKey.pem', 'rb') as p:
        privateKey = rsa.PrivateKey.load_pkcs1(p.read())
    return privateKey, publicKey


def decrypt(ciphertext, key):
    try:
        print(ciphertext)
        return rsa.decrypt(ciphertext, key).decode('ascii')
    except:
        return False


def verify(message, signature, key):
    try:
        return rsa.verify(message, signature, key, ) == 'SHA-1'
    except:
        return False


privateKey, publicKey = loadKeys()

ciphertext = input("message to decipher: ")
print(ciphertext)
text = decrypt(ciphertext, privateKey)

if text:
    print(f'Message text: {text}')
else:
    print(f'Unable to decrypt the message.')

whenever I encode text and then paste it into the input of the decryption program, it returns cannot decode message. If anyone knows why this is, I would love some help. Thanks!

The byte string ciphertext is converted to a character string by str() or at the latest by input() .

Example: The 2 byte string b'\x11\xed' is converted by str() or by input() into an 11 bytes character string like a UTF8 encoding reveals: b"b'\\x11\\xed'" .

This character string must be converted back to the original byte string before decryption, which does not happen (or happens incorrectly) in the posted implementation (s. also the comments).

The problem can be easily solved if the ciphertext is Base64 encoded. This string can then be passed to input() via copy/paste and Base64 decoded before decryption. If it is necessary to store the ciphertext, it is recommended to store the raw ciphertext because of the Base64 overhead.

The following code implements encryption and decryption using Base64 encoding/decoding:

import rsa
import base64

def generateKeys():
    return rsa.newkeys(1024)

def encrypt(message, key):
    return rsa.encrypt(message.encode('ascii'), key)

def decrypt(ciphertext, key):
    try:
        return rsa.decrypt(ciphertext, key).decode('ascii')
    except:
        return False

(publicKey, privateKey) = generateKeys()
encryptme = 'The quick brown fox jumps over the lazy dog'

# Encryption
ciphertext = encrypt(encryptme, publicKey) # store raw ciphertext in file system 
ciphertextB64 = base64.b64encode(ciphertext).decode('utf8')
print(ciphertextB64)
ciphertextB64Input = input("message to decipher: ") # Enter the ciphertext with copy/paste
decrypted = decrypt(base64.b64decode(ciphertextB64Input), privateKey)
print(decrypted)

The same applies to signing:

def sign(message, key):
    return rsa.sign(message.encode('ascii'), key, 'SHA-1')

def verify(message, signature, key):
    try:
        return rsa.verify(message.encode('ascii'), signature, key) == 'SHA-1'
    except:
        return False

# Signing
signme = 'The quick brown fox jumps over the lazy dog'
signature = sign(signme, privateKey) # store raw signature in file system
signatureB64 = base64.b64encode(signature).decode('utf8')
print(signatureB64)
signatureB64Input = input("signature to verify: ")
verified = verify(signme, base64.b64decode(signatureB64Input), publicKey)
print(verified)

Note that there is another bug here: in rsa.verify() message must be replaced by message.encode('ascii') .

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