I am writing an application that involves checking to see if data has been created by me. I do this by encrypting the data with the private key on my server, and then decrypting it using the public key on the client. If the result matches the hashed version of the message then I know it came from me. However, I'm using RSA and so that means I have to flip the keys since I know you can't encrypt with a private key.
Here is how I am generating my keys:
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
with open('private_key.pem', 'wb') as f:
f.write(pem)
pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
with open('public_key.pem', 'wb') as f:
f.write(pem)
However, here private_key
is my public key and public_key
is my private key. Is there something I need to change? I've heard public keys are generally smaller but I don't understand enough of the settings to tell if they're symmetric or not.
Any advice would be appreciated.
Thanks.
EDIT: They are definitely not symmetric. As suspected, my public key is much shorter. How do I reverse this?
EDIT2: How about signing/verifying instead?
Server:
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding
import base64
import uuid
import hashlib
message_id = uuid.uuid1()
with open("private_key.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
message = bytes(hashlib.sha3_256((str(message_id) + str(valid)).encode("utf-8")).hexdigest(), "utf-8")
encrypted_data = private_key.sign(
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA3_256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA3_256()
)
encrypted_data = str(base64.b64encode(encrypted_data), "utf-8")
Client:
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.exceptions import InvalidSignature
import hashlib
import base64
encrypted = response["encrypted"]
message_id = response["message_id"]
valid = response["valid"]
with open("public_key.pem", "rb") as key_file:
public_key = serialization.load_pem_public_key(
key_file.read(),
backend=default_backend()
)
message = bytes(hashlib.sha3_256((str(message_id) + str(valid)).encode("utf-8")).hexdigest(), "utf-8")
encrypted = base64.b64decode(encrypted)
try:
public_key.verify(
encrypted,
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA3_256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA3_256()
)
print("Yes")
except InvalidSignature:
print("No")