Why does RSA decryption fail in python when encrypted in js? - python

I'm creating python server and js client. To authenticate users, I used RSA. After server sent public key, client encrypt msg using js 'crypto' module and return encrypted message. But I can't decrypt message in server using python 'cryptography'.
Here is my server(python) code.
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
import socketio
from aiohttp import web
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
sio = socketio.AsyncServer(async_mode='aiohttp', cors_allowed_origins='*')
app = web.Application()
sio.attach(app)
def main(): //key import from .pem
with open("private_key.pem", "rb") as key_file:
key.private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
with open("public_key.pem", "rb") as key_file:
key.public_key = serialization.load_pem_public_key(
key_file.read(),
backend=default_backend()
)
#Serialize to send as a message
key.public_key_serialization = key.public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(key.private_key_serialization.decode("utf-8"))
#sio.event
async def get_public_key(sid, data):
await sio.emit('public_key', {
'public': key.public_key_serialization.decode('utf-8'), #send public key
'data': encrypted}, room=sid)
def decrypt(sid, data): #decrypt from encrypted message
original_message = key.private_key.decrypt(
data["data"],
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
print(original_message)
the data["data"] is the encrypted message like b"'\xf5N\xb9\xe9\xfd\xac\x84'\xc9\x1dKkc\xb2%\xb7\xd2\xcb\x1a4\x8c\xean\xf2\x9b\xab^\xb9\x . . .
It is my client(js) code.
var crypto = require("crypto");
var buffer =require('buffer').Buffer;
const io = require("socket.io-client");
const socket = io.connect('http://localhost:8080');
var msg = crypto.publicEncrypt({
key: data["public"],
oaepHash: 'sha256'
}, buffer.from("encrypt me!")) #ciphertext: encrypt me!
console.log(msg)
(editor recognizes below text as code..)
the data["public"] is
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwvZD07r1IDHYMnDZqVql
glro/loIY9lUTpqdKaZigB0XE82pyDiqPZA2jzgxkAQJBKRO5u5PiN+UC2Ur5oqM
fQUyDefsKuC5c5rpnJK1px6IsjDzCym5DPXZoVbb7nYzmy0rLLwQZC/hZqIiuP/Y
y+3Orz49I+KSI4Lhq2kRWYhLUUhecdF+AJndkbZtWjsW1wc1tsCV0knQuVilPpwe
OmGgYQD/5xqcJRHHsYryGxFMW/2YJ1eD+3EzEUpRkXxaHIc9Uagc8TbT8uVbeoXi
Zrbl2BkfO6O8swBF+VgG3d6qZZoEyrk2TS3rB6oQSQWPFVissh4sFVOcjh37hdB2
BwIDAQAB
-----END PUBLIC KEY-----
private key is
-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEAwvZD07r1IDHYMnDZqVqlglro/loIY9lUTpqdKaZigB0XE82p
yDiqPZA2jzgxkAQJBKRO5u5PiN+UC2Ur5oqMfQUyDefsKuC5c5rpnJK1px6IsjDz
Cym5DPXZoVbb7nYzmy0rLLwQZC/hZqIiuP/Yy+3Orz49I+KSI4Lhq2kRWYhLUUhe
cdF+AJndkbZtWjsW1wc1tsCV0knQuVilPpweOmGgYQD/5xqcJRHHsYryGxFMW/2Y
J1eD+3EzEUpRkXxaHIc9Uagc8TbT8uVbeoXiZrbl2BkfO6O8swBF+VgG3d6qZZoE
yrk2TS3rB6oQSQWPFVissh4sFVOcjh37hdB2BwIDAQABAoIBAQCdxH961W4L0Yos
t1nMTEhnRn4JZn4nnvU0brYDwFsxZVkJc4KTPhe1ngAowcaJzlol4XjgM7U1BAhf
eE2gUDoD6bJpwmZBBH3OaWvmgmpxhKoF2Mq1G9xd+o1UnF95hzmXt2Oa3c095ek3
Drmej5u22whIk8sSQQUVq5JHDc02b0U/XyBHn+OqNMYn7EFsYHeSUMIcx58bQ/u4
Tvi0NdEovVciURFq173XM+BK+8oRnJBpEglskWfA6kuu5+NlpQgkzIM9vDutQyL0
Y9rJGxg3CvTQhn8vZx6COPyLRXTPc6IOExpwsTVmRAshGxbMbt6yXErCagge7VQh
mNymoqNRAoGBAOB2He8Ge7/tXeuTAptb6vgbNeoUjBxFNYmpDnEbplnM9Ydmgy/k
//2lNOu8bRTxk2wVKx35br/BcrJTlTmjzd2CYWJvBKQ9vYznAX2gVJ4MZXX/vHNO
GZEc1bwn5TaxUwywl0Q51TLT6KlHF+PBIttkQjCErbDhnMlrojlyNGw1AoGBAN5b
DY01XgKIUWegt4pRVG+LiQ+Oz547ksWIM338QP7o6BFLn85jAdByFmt94xgEUe4c
5FNRfZWOgbNLUSlbQ6AmUFVPDr3xfQDEKk65ci9dK4t/S7rajuHGHHzhW8wV/bYp
m7/N5ax0FEsyuJQpP0e0KambT1EJnWti6SERCQjLAoGBAMPers5XJQPdeZjJZ3v0
4PzymcCTf5Rn3IktChovm6E/Vn56OT5BIhXP5XdUrQeaqx+k9UQp1rfkclck0tJC
m7GRRbPk1vMPoWnkZ4udrllgzeUDbgpce7kCpYyUb9OjN6qaKtXxdZbuDlgxXqpz
bhxux8eY8AyrQ+sMTrq8avyFAoGBANOQJvC4Wl5mfa3vyTKd94y6YwqegwS3AgtY
cEXrAZyI1mW+YqrooQ1Hv/U+rhhn49x/OO/dlXP7R4TkoLCM2WdDjSPeONSZNKrJ
+sc0w2Q1bf0ofVGoKlK/QNPBSKqCMghkxoBU07amK7jw5ZZzOHZtAUcTMwCT+Wf3
kIGZx9LJAoGBAIWbpW1FIGiTJUzQDa2Y2n0S3P7vMpAI1YlIC32hGzKjtwKR4sWr
jqIgj7Zw67u3O8h0lwqyAMFxoMBfBbc2A3ctapPwHEs6TFqA5c1WKptt9LiqrP7n
oaD+XcUrgIed4gSa4KoXPoo2AFu3eyFq47/6jmV9rS42hut8s+KAds7r
-----END RSA PRIVATE KEY-----
According the docs, both use OAEP padding.
python cryptography - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/#:~:text=RSA%20private%20key.-,decrypt,-(ciphertext%2C%20padding)
js crypto - https://nodejs.org/api/crypto.html#crypto_crypto_privatedecrypt_privatekey_buffer
I really don't know why it is failed.. Any advise, comments and suggestions will be appreciated.

Related

Asymmetric Encryption with node js and Decryption with Python

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

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();

RSA encrypt and decrypt in python for url

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

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

Creating RSA signature using node.js and verifying using 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)

Categories

Resources