This should be simple (famous last words)
In the terminal, i can run this command:
winpty openssl genrsa -des3 -out my_rsa_key_pair 2048
How can I do the exact same thing using pyca/cryptography ?
The Fernet method is not used as a method for generating RSA keys. Therefore, Fernet-based RSA key generation is not supported by pyca/cryptography. However, you can generate RSA keys in the pyca/cryptography package like this:
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
private_key = rsa.generate_private_key(
public_exponent=65537, # Commonly used public exponent
key_size=2048, # Key size in bits
backend=default_backend()
)
public_key = private_key.public_key()
Hope this helps.
Related
I have used openssl to encrypt data using below command:
openssl cms -encrypt -in test.data -inform PEM -recip certificate.pem -outform PEM -out test_encrypted_data.txt
Now I want to decrypt above encrypted data using python. I have tried below code, but it is not working and is throwing:
ValueError: Ciphertext with incorrect length.
Code:
from Crypto.Cipher import PKCS1_OAEP, AES
from Crypto.PublicKey import RSA
from OpenSSL import crypto
import base64
data = open("test_encrypted_data.txt").read()
data = data.replace("-----BEGIN CMS-----", "").replace("-----END CMS-----", "")
data = base64.b64decode(data)
private_key = RSA.import_key(open("private_key_no_pass.pem").read())
decryptor = PKCS1_OAEP.new(private_key)
decryptedtext = decryptor.decrypt(data)
print(f"Decrypted Text : {decryptedtext.decode()}")
Check if openssl des 'base64' encode.
Probably -base64 parameter is missing in openssl.
So the text is encrypted but not base64 coded by openssl, and then your code does base64 decode and decrypts it.
Thanks all I have used openssl commands to decrypt file in python
decrypted_data = subprocess.check_output(
f'echo "{encryptedtext}" | openssl cms -decrypt -inkey services/private_key_no_pass.pem -inform PEM ',
shell=True)
I have trouble with encryption and description using node js and python.
First create public/private keys,
openssl genrsa -out private_key.pem 4096
openssl rsa -pubout -in private_key.pem -out public_key.pem
then in nodejs
const crypto = require("crypto")
const fs = require("fs")
var encrypted = crypto.publicEncrypt({
key: fs.readFileSync('./public_key.pem', 'utf8'),
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256'},
Buffer.from("123456"))
encrypted = encrypted.toString('base64')
Now I try to decrypt encrypted in python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
with open("./private_key.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
original_message = private_key.decrypt(
encrypted,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
the decryption method raises an error
ValueError: Ciphertext length must be equal to key size.
I think the problem is different padding but I do not know how to use proper paddings.
These are my sources
Link1
Link2
My task is to encrypt ID and pass to url. After then from url, fetch encrypted ID and decrypt the ID. I have to perform this task in python.
I am using RSA algorithm.
I am able to do encryption of ID but I am stuck at decryption. Also I don't know how to decrease the length of the encrypted ID. Because when I add encrypted ID to url which is quite long.
Your help or any new suggestion will be helpful.
Thank you
Below is the code I am doing encryption
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
import codecs
# Below commented code to Generate Private and Public Key
# key = RSA.generate(1024)
# private_key=key.exportKey()
# public_key=key.publickey().exportKey()
private_key = """-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCXmxgIXMkim2EBdiHjJLsgHxqhGUbO3n64MgAO+Ugbr2GVkchV
aQUUWnNacmMOjq7h6OO1HLvH/tyow9d5XQlSjVlo28i9hHw40CTcBh0F3Fnzylwo
8YHt1b4wSdO970ZnxSrtF6D8J3KPiPhzcJjrBpOU6seF46iuOwPFnjSg/QIDAQAB
AoGAAUtvcBrYE4s/en4MxLN6mZ1KYpfO//3sbRxC3d3echtppO0CyJ/wotTcPqh9
ahFpMuqvOcu4sCOKtNzp89JfPamHhjGU9xEGtqGWDWUrRjBAX22qq9Tkwlxhyoi1
VYPK14nJPJYIFVA1tQvKNjQcEpN8rkaqesM9MGsbnL5r9C0CQQC4vmWhD7aHH3I7
T9LTwvABXiaUYe39EOtJ8nc+4E9StwtUSQ/AGuGxrIyYfTHX70nWMDTikorEltWm
rncHN1RvAkEA0hSow9/qe0CSmp5On14w6Ev+5glm6c2YqoaKAWfRggTrBQkIN1nh
m0Wqbk4gqvxCtJ26Sgi4d62GG93WRipPUwJAe90L/qSuWII48JNgYyJ8EC6z5yCR
k+7YEkhCsyFpjae0LNqfeMmNMLbjvQmTdZe2Balki9R8vbnznUG0BF6QeQJAdNxZ
JNyiKv24j5oQUkarHg1oNb51KQndKr68dhuyR4lE0wA7Oc8d2KngLIv5UCQTVzWG
Mzi2pJw6RbYZQ961UQJBAIbJOhfvy+T99aDxQKMWV0vEP93ebzlK1WW9MjhbzlIi
UXfH1dJFtNZiZO5eM7oGl9Icyb6aGHx91c17zOptXHo=
-----END RSA PRIVATE KEY-----"""
public_key = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXmxgIXMkim2EBdiHjJLsgHxqh
GUbO3n64MgAO+Ugbr2GVkchVaQUUWnNacmMOjq7h6OO1HLvH/tyow9d5XQlSjVlo
28i9hHw40CTcBh0F3Fnzylwo8YHt1b4wSdO970ZnxSrtF6D8J3KPiPhzcJjrBpOU
6seF46iuOwPFnjSg/QIDAQAB
-----END PUBLIC KEY-----"""
id = "5070930456"
h = SHA256.new(id)
priv_key = RSA.importKey(private_key)
pub_key = RSA.importKey(public_key)
singer = PKCS1_v1_5.new(priv_key)
signature = singer.sign(h)
hexify = codecs.getencoder('hex')
m = hexify(signature)[0]
#Output Encrypted ID
print m
Encrypted ID Output: 313729e2535c19f6a7121a8c80529b3d49ba1cdf7277aabddd2c04ff41ee85d55f5edc1c9e798da381cc0a5aabff529be62fa7ee6be61b1a0d25c57c45c9e6f65f726bb35fd5646bf7ce495d9a12bbe88688bd287bc667b5ff0f4a90218377cc2a0454e448ab53940a2457e20553deeb7b23c78d259660e9362be572384be344
I have been given a public key by my client, and I want to send him a text message which would be encrypted with his public key. The public key is with .pub extension.
I am trying to do this in bash via openssl command and via python using pycrypto module with no luck. I am a novice with no experience in cryptography.
How can I go about this.Thanks in advance
public_key
Suppositions:
The public key given by your client is in "key.pub" file
Taking the input from the user at run time for the string or text to be encrypted in a variable named, "msg".
Already installed Crypto.PublicKey library using command "sudo pip install Crypto.PublicKey"
Code:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5
with open("key.pub", 'r') as f1:
pubkey = f1.read()
msg = raw_input("Enter String to be encrypted: ")
print("raw string->", msg)
keyPub = RSA.importKey(pubkey) # import the public key
cipher = Cipher_PKCS1_v1_5.new(keyPub)
cipher_text = cipher.encrypt(msg.encode()) # now we have the cipher
print("cipher text->", cipher_text)
Format for the Key in the file:
The format of key in the file should be like this,
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAybVqRvfYvWbLsB98BqkD
lWd0/5y6SyhHt6/r6M0l7JXBweqMvxVt7XmI2yqPL56YxzcgQ8ycDkoqHJ+XozgP
iRnLNpYRlCzsiaOElbmQcnrI8iOb9Ahm6j0cbBB1S8VNvD+u9RQJt53zPxPj8/Dq
f1oNGFXOM8udNYWZaRCukLs/TumsAn0a+BF4639WtFiUvTWdVhlyvCQTs49ytRkH
rXH30RkB528RIvTGeW8xBTV4NaiTIzAEKCVSPagLr4Hzbb9b5+bODic/zkLGQazy
/NKOFgiB7kD2+WEMcuhTr5noeXau0PDAhgmrBhzzWOjUwwaO+ACvJLkPXZfjhy7P
+wIDAQAB
-----END PUBLIC KEY-----
As far as I understand, I should be able to use RSA to ensure authenticity or privacy, as I wish. In my case, I want to ensure authenticity so I encrypt the data with the private key and allow anyone to decrypt it with the public key. The data is not really secret but I need to guarantee that it was created by the owner of the public (and private) key.
When I try to decrypt using PyCrypto I get No private key error from PyCrypto. The code is this:
def _decrypt_rsa(decrypt_key_file, cipher_text):
from Crypto.PublicKey import RSA
from base64 import b64decode
key = open(decrypt_key_file, "r").read()
rsakey = RSA.importKey(key)
raw_cipher_data = b64decode(cipher_text)
decrypted = rsakey.decrypt(raw_cipher_data)
return decrypted
I'm calling it with the path to the public key file (in OpenSSH format.) The encrypted data isn't generated by me and it was not done with Python but PHP. In PHP there's a openssl_public_decrypt function that decrypts this data easily.
Is it possible at all to decrypt using the public key with PyCrypto?
That is totally insecure, because you are using raw RSA without padding.
Your application needs a signature, so you should not be dealing with encryptions and decryptions. For instance, PKCS#1 v1.5 is a good protocol, even though the signature is a piece of data that must be appended to what you want to prove the authenticity of.
To verify a PKCS#1 v1.5 signature in Python, you do:
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA
rsa_key = RSA.importKey(open(verification_key_file, "rb").read())
verifier = PKCS1_v1_5.new(rsa_key)
h = SHA.new(data_to_verify)
if verifier.verify(h, signature_received_with_the_data):
print "OK"
else:
print "Invalid"
I would strongly recommend to change the PHP code so that it creates such a signature.
Your function is correct. You just need to be giving it the path to your private key in order to decrypt instead of your public key. The public key is for encrypting, the private key is for decrypting.
def _decrypt_rsa(decrypt_key_file, cipher_text):
'''
Decrypt RSA encrypted package with private key
:param decrypt_key_file: Private key
:param cipher_text: Base64 encoded string to decrypt
:return: String decrypted
'''
from Crypto.PublicKey import RSA
from base64 import b64decode
key = open(decrypt_key_file, "r").read()
rsakey = RSA.importKey(key)
#optionally could use OAEP
#from Crypto.Cipher import PKCS1_OAEP
#rsakey = PKCS1_OAEP.new(rsakey)
raw_cipher_data = b64decode(cipher_text)
decrypted = rsakey.decrypt(raw_cipher_data)
return decrypted