Creating RSA signature using node.js and verifying using python - python

I'm trying to create a signature in node using this code:
var crypto = require('crypto');
var data = 'some data'
var signer = crypto.createSign('RSA-SHA256');
signer.write(data, 'base64');
signer.end();
var signature = signer.sign(privateKey, 'base64');
The signature and data are sent to python server.
Now I'm want to verify it using python code:
from base64 import b64decode, b64encode
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
rsakey = RSA.importKey(public_key)
signer = PKCS1_v1_5.new(rsakey)
digest = SHA256.new()
digest.update(data)
signer.verify(digest, b64decode(signature))
The verification fails.
When I use the same language for both sign and verify it works.
Any thoughts?

I had the same problem, and have found this to work:
import rsa
rsa.verify(message, signature, public_key)

Related

Get public key from base64 encded string in Python

I have a certificate which is base64encoded.
I am able to get the public key using Java like this:
private static final String CERTIFICATE = "MIIGXDCCBUSgAwIBAgIMNrcrYQDXRuN4uLHeMA0GCSqGSIb3DQEBC........";
X509Certificate cert = (X509Certificate) CertificateFactory.getInstance("X.509")
.generateCertificate(new ByteArrayInputStream(Base64.getDecoder().decode(CERTIFICATE)));
PublicKey publicKey = cert.getPublicKey();
But now I try to do the same using Python 3. I am not able to find any example how to get the public key from base64encoded string.
Could someone help or point me to some sample code to get public key which I can use to encrypt JWT later.
Thank you
David
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
cert_str = '-----BEGIN CERTIFICATE----- MUST HAVE THE BEGIN AND END CERTIFICATE -----END CERTIFICATE-----';
cert_obj = load_pem_x509_certificate(str.encode(cert_str), default_backend())
public_key = cert_obj.public_key();

"Incorrect decryption" in decryption RSA python code

i have this code that suppose to decode base64 encoded RSA text (by its key) but it doesn't work.
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import binascii
import base64
f = open('mykey.pem','r')
keyPair = RSA.import_key(f.read())
encoded = b'base64_encoded_text'
encrypted = base64.decodebytes(encoded)
decryptor = PKCS1_OAEP.new(keyPair)
decrypted = decryptor.decrypt(encrypted)
print('Decrypted:', decrypted)
The error is: "Incorrect decryption".
Does somebody know what could be the problem?

encrypt text message using rsa public key

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

Decrypt using an RSA public key with PyCrypto

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

Python for RSA signature

from Crypto.Signature import PKCS1_v1_5 as pk
from Crypto.PublicKey import RSA
privatekey=RSA.importKey(open('pkcs8_rsa_private_key.pem','r').read())
def sign(self,signdata):
h=SHA.new(signdata)
signer = pk.new(privatekey)
signn=signer.sign(h)
signn=base64.b64encode(signn)
return signn
Just like this, but my privatekey is a string not a file. How I do it?
And how can I make privatekey string to pkcs8 format?

Categories

Resources