SMIME.smime_load_pkcs7 (_bio): M2Crypto.SMIME.SMIME_Error: no content type - m2crypto

I have problems loading a pkcs#7 file and ask your help to figure out what I'm doing wrong.
I run M2Crypto-0.21.1 with OpenSSL 0.9.8g (as present in Ubuntu 9.4) and built with SWIG 1.3.36 and python 2.6.2.
"python setup.py test --test-suite=tests.test_smime" runs 15 tests with exit status "OK"; so the installation seems to be ok.
I created a pkcs#7 file in PEM format with a digital signature program and tested it with OpenSSL from the command line:
openssl smime -verify -inform PEM -in mandato-PEM.p7m -noverify
which prints the content contained in the envelope (a text file that I signed) and "Verification successful". So OpenSSL (same version as used by M2Crypto) seems to like my file.
However, when I try the same in M2Crypto, it chocks right in the beginning on:
p7, data = SMIME.smime_load_pkcs7('mandato-PEM.p7m')
I get the following exception:
Traceback (most recent call last):
File "./sign.py", line 110, in <module>
p7, data = SMIME.smime_load_pkcs7('mandato-PEM.p7m')
File "/usr/local/lib/python2.6/dist-packages/M2Crypto-0.21.1-py2.6-linux-i686.egg/M2Crypto/SMIME.py", line 91, in smime_load_pkcs7
p7_ptr, bio_ptr = m2.smime_read_pkcs7(bio)
M2Crypto.SMIME.SMIME_Error: no content type
While I have found information of a problem in Ubuntu (https://lists.ubuntu.com/archives/ubuntu-server-bugs/2010-July/038683.html), it seems to me that this cannot apply here since I built the latest M2Crypto manually and the test suite works fine.
Any help in resolving my problem would be highly appreciated!
many thanks
-bud

After a lot of sweat, here the solution for others who run into the same issue.
I was following the recipe http://code.activestate.com/recipes/285211/ and found many discussions on the web that just "verify(p7)" [method of SMIME] wasn't correct and "verify(p7, data)" was the right thing to do.
This applies only to SMIME documents where the signature is detached. My pkcs#7 file, and all other Italian digitally signed documents, are pkcs#7 envelopes that contain both the signature and the file content (in DER format).
Enveloped p7m files have to be verified as follows:
s=SMIME.SMIME()
st = X509.X509_Store()
st.load_info(trustedCAsPEMfileName)
s.set_x509_store(st)
p7bio = BIO.MemoryBuffer(p7strPEM)
p7 = SMIME.load_pkcs7_bio(p7bio)
certStack = p7.get0_signers(X509.X509_Stack())
s.set_x509_stack(certStack)
try:
docContent = s.verify(p7)
except SMIME.PKCS7_Error, e:
print "An exception occurred!!!!"
print e
To test that this works, I edited the p7m file such that the signature doesn't verify anymore and it correctly prints out "digest failure".

You can also verify a .p7m file (attached DER format) directly but you need to load PKCS #7 object from DER format by m2 direct call to OpenSSL (m2.pkcs7_read_bio_der(input_bio._ptr())) because there is no function for this inside M2Crypto SMIME module. For a proposed patch see Small patch to SMIME.py.
Here a sample code:
import logging
from M2Crypto import SMIME, X509, m2, BIO
certstore_path = "/etc/ssl/certs/ca-certificates.crt"
file_descriptor = open('test_file.p7m', 'rb')
input_bio = BIO.File(file_descriptor)
signer = SMIME.SMIME()
cert_store = X509.X509_Store()
cert_store.load_info(certstore_path)
signer.set_x509_store(cert_store)
try:
p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1)
except SMIME.SMIME_Error, e:
logging.error('load pkcs7 error: ' + str(e))
sk3 = p7.get0_signers(X509.X509_Stack())
signer.set_x509_stack(sk3)
data_bio = None
try:
v = signer.verify(p7, data_bio)
except SMIME.SMIME_Error, e:
logging.error('smime error: ' + str(e))
except SMIME.PKCS7_Error, e:
logging.error('pkcs7 error: ' + str(e))
Code Source: pysmime core

If you only want to extract the original file from the .p7m one (without verifying it), you need to install M2Crypto with pip install M2Crypto (you must probably run sudo apt-get install libssl-dev before) and then run this Python code:
from M2Crypto import BIO, SMIME, X509
# Load file in memory just to showcase BIO usage
with open('file.p7m', 'rb') as file:
p7m = file.read()
smime = SMIME.SMIME()
smime.set_x509_store(X509.X509_Store())
smime.set_x509_stack(X509.X509_Stack())
original_file_content = smime.verify(
SMIME.load_pkcs7_bio_der(BIO.MemoryBuffer(p7m)),
flags=SMIME.PKCS7_NOVERIFY
)
You can use SMIME.load_pkcs7, SMIME.load_pkcs7_bio, SMIME.load_pkcs7_der instead of SMIME.load_pkcs7_bio_der according to your use case: in-memory (_bio) or on file system .p7m file, and PEM or DER (_der) format.

The best reference I found to sign and unsign is the M2Crypto tests here:
http://svn.osafoundation.org/m2crypto/trunk/tests/test_smime.py
def test_sign(self):
buf = BIO.MemoryBuffer(self.cleartext)
s = SMIME.SMIME()
s.load_key('tests/signer_key.pem', 'tests/signer.pem')
p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
assert len(buf) == 0
assert p7.type() == SMIME.PKCS7_SIGNED, p7.type()
assert isinstance(p7, SMIME.PKCS7), p7
out = BIO.MemoryBuffer()
p7.write(out)
buf = out.read()
assert buf[:len('-----BEGIN PKCS7-----')] == '-----BEGIN PKCS7-----'
buf = buf.strip()
assert buf[-len('-----END PKCS7-----'):] == '-----END PKCS7-----', buf[-len('-----END PKCS7-----'):]
assert len(buf) > len('-----END PKCS7-----') + len('-----BEGIN PKCS7-----')
s.write(out, p7, BIO.MemoryBuffer(self.cleartext))
return out
def test_verify(self):
s = SMIME.SMIME()
x509 = X509.load_cert('tests/signer.pem')
sk = X509.X509_Stack()
sk.push(x509)
s.set_x509_stack(sk)
st = X509.X509_Store()
st.load_info('tests/ca.pem')
s.set_x509_store(st)
p7, data = SMIME.smime_load_pkcs7_bio(self.signed)
assert isinstance(p7, SMIME.PKCS7), p7
v = s.verify(p7, data)
assert v == self.cleartext
t = p7.get0_signers(sk)
assert len(t) == 1
assert t[0].as_pem() == x509.as_pem(), t[0].as_text()
Be carefull with the documentation (http://svn.osafoundation.org/m2crypto/trunk/doc/howto.smime.html) because it is not updated.
See this patch:
https://bugzilla.osafoundation.org/show_bug.cgi?id=13020

Related

Troubleshooting type "PGPKeyring" is not callable

Working with PGPy and using PGPKeyring.
My code is pretty straigtforward.
I first have a function to fetch the keys considering that
encryption requires a public key, while decryption requires a private or secret key.
We have a GoAnyWhere server that is being demoted and all this encryption has to be moved to Python.
import sys
import pgpy
from pgpy import PGPKey
from loguru import logger
def fetch_keys(self.action):
#Select the correct key
if self.action == "encrypt":
#Encryption requires a public key...go get it.
KR = self.PGPKeyServer + self.publicKeyPath + self.publicKeyRing
KeyRing = pgpy.PGPKeyring(KR)
with KeyRing(self.keyID) as key:
#Unload a loaded key and its subkeys.
unloadKR = KeyRing.unload(key)
logger.info(f"Pub Key Ring has unloaded - {self.keyID}")
PublicKey, _ = PGPKey.from_file(unloadKR)
It says "Object of type "PGPKeyring" is not callable"
It's also saying "Type of "unload" is "(key: Unknown) -> None"
I'm assuming that I need to extract the key from the ring before I load it into PublicKey
After this part is working I'll do the following..
elif self.action == "decrypt":
#Decryption requires a secret key...go get it.
KeyRing = self.PGPKeyServer + self.secretKeyPath + self.secretKeyRing
KeyRing = pgpy.PGPKeyring(KeyRing)
with KeyRing(self.keyID) as key:
#Unload a loaded key and its subkeys.
unloaded = KeyRing.unload(key)
logger.info(f"Secret Key Ring has unloaded - {self.keyID}")
SecKey, _ = PGPKey.from_file(unloadKR)
And the secret key will be locked with a passphrase where I'll do something like...
with SecKey.unlock(self.passphrase):
# Secretkey is now unlocked
assert Seckey.is_unlocked
If anybody has worked with PGPy before and can give me some advice on the best way forward it would be appreciated.
For now I just want to get line 1 through 12 working so I can run the script passing "encrypt" as the parameter and get some logged result. Is "with KeyRing(self.keyID) as key:" not the proper syntax?
I've tried to work with other python libraries for encryption and decryption and think PGPy has the best examples to follow. I haven't been able to run the script yet with any success.
My run parameters will be passed like so.
def run(self) -> None:
if self.action == "encrypt":
PubKey = fetch_keys(self.action)
# self.do_encrypt(PubKey)
elif self.action == "decrypt":
SecKey = fetch_keys(self.action)
# self.do_decrypt(SecKey)
else:
logger.error(
f"Encrytion for: {self.file_name} - Invalid action '{self.action}'"
)

decodestrings is not an attribute of base64 error in python 3.9.1

After upgrading from python 3.8.0 to python 3.9.1, the tremc front-end of transmission bitTorrent client is throwing decodestrings is not an attribute of base64 error whenever i click on a torrent entry to check the details.
My system specs:
OS: Arch linux
kernel: 5.6.11-clear-linux
base64.encodestring() and base64.decodestring(), aliases deprecated since Python 3.1, have been removed.
use base64.encodebytes() and base64.decodebytes()
So i went to the site-packages directory and with ripgrep tried searching for the decodestring string.
rg decodestring
paramiko/py3compat.py
39: decodebytes = base64.decodestring
Upon examining the py3compat.py file,i found this block:
PY2 = sys.version_info[0] < 3
if PY2:
string_types = basestring # NOQA
text_type = unicode # NOQA
bytes_types = str
bytes = str
integer_types = (int, long) # NOQA
long = long # NOQA
input = raw_input # NOQA
decodebytes = base64.decodestring
encodebytes = base64.encodestring
So decodebytes have replaced(aliased) decodestring attribute of base64 for python version >= 3
This must be a new addendum because tremc was working fine in uptil version 3.8.*.
Opened tremc script, found the erring line (line 441), just replaced the attribute decodestring with decodebytes.A quick fix till the next update.
PS: Checked the github repository, and there's a pull request for it in waiting.
If you don't want to wait for the next release and also don't want to hack the way i did, you can get it freshly build from the repository, though that would be not much of a difference than my method

Signing for requesting a jwt to use on an API in python3

I try to generate a jwt token for connecting to transip api, but can't figure out how to generate as Signature to request one. I would prefer to do it in Python3. How should I do this?
Api documentation of transip and see the section of Authentication
I did write some code which fails:
#!/usr/bin/env python3
import OpenSSL
key='''-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDIYjaYtIh8EDSu
wmVxRaXm6gtA9cRGds2juYvO+za8oQ+36OS4J35Hig/XE0Zr1hrfjGfnuy3bubrj
zB/w3Hg4Kl63oBel/2HSmaNczR12dMGZzMqyHHXyZKl/cYjzhbgAucSM/q+inbuL
1gK0O9+Ov2Uc8iMfeRBG/XBNo5QVVzWYF+BSmojobawGMIR/LKKKJL6HNzdcz5yr
PAWR0HfukpwuZcehEJca/TLgUf/FoBfRKm+tFVyVNYB6v2kvI0ASMMhsnsEnQ0CX
0mi9cmyXB6iB/5SnwKkXZIwPXwmyXvSwIdZiTU70QNlfGKrIGuv5+fDNd1+g7XDV
yjzS9HObAgMBAAECggEAIDSQu8hAK1hbbz71GNhtyogRGPam/gA4GrlGfBSp/nUQ
VqmKoQJP7GWHGDUT218E4KrrRDY0L51RKS10cLyuYbCFmpOTWW2LJlLlC5Q3yQMI
3pQoe6nRVwzQpRf1P9Zc9Vjl+xcv2T3ql5Xkx1zcGFAwiw9rj7JgaFhxRTkmIquh
oyHkMHW74hSVlx55HhDtc1uTK3aWnEhKJfj/dRmA5Hald3ixoaASsZWA3ZTr7B8R
b/2mAGml+/dEYuspbkIZW9Bryv7UlpT2E9/7SpV8c05Spehl12EfMcJhaFJDe1G4
kkCqbl8Uks+jm9/aWSUIUzcHuZDw1PAiVqPVVcyfkQKBgQDtHp89U1QZBuAXI3KM
FOeOFUD+Vb4oLhTyWVsWE6jJjxfGVyGtIRNw6rHrHumlN8Fpb4ijEdvoNQkPiKnl
HYGnUp7BkbvpgncjL6b4br3b9cXtcpDHdTD5dAir+j3sDrVvAG6YXnuyZONOXxXm
oVp/sd+DBArBQFqHgQICOxgNowKBgQDYVsaZEoa22tuhrVfo5UxoRq+hAnMN5cTv
iGof1Qt2t2BYVEjpz2YpVQ/ksCHbtSVxRzw00qW4xzHNzxJ4JkDAlerxQy+nqBCp
emWMADs2H/ALTvCFaEA+rGLe+MYf0ANaw94AbR44jKNcGqMrwwVQpC9CY3/C0A9L
pg1ssZ/xqQKBgFZrG6QRE4xPeipUq/GryLx6uIY5H6WrLc0pjc3c+l4DPan2pXpg
nKJBlvhW+tZRHLddg9HSt2/IrHWx3CF5gIBH1z46695twxfazSKr0Zwx1aH1aBiZ
eHDhvitXd2vp7Gv5H1V+0dwxcrpkYyn70mzJmek49uZ5msTZ2q6PdPO7AoGAapi3
Wo1KW6cTOWLUQilZsLfDqi4uytZAZ1ZsFCtBbsmEa4F8O9i5mfwTzLcMt9lWDa7v
94cjqRxdae9yRkly9nHoReC5Bn9FVny8tHMYud6axLesw89OeJMwVHV4CgzQ2lRQ
ex1JGswRYjyt0c5SPB3qO2gTd8ZVAw1a6AfNq6ECgYB/tndONcYppD/j3278+3Wy
EV/P0CEBVrvXboUyxkFykZ5CFYkpNEisQ4Imu9PUGCOqSxxOoXQ2TyyzIb9nY1g1
K2Xs9J9sOEoGmmWJ+RJkHiwNkAIAbuYaluqtRyqY0w2z19JZKRv1u9vuWP1+f5G6
+5aF0x9Xgt2Tvq3T1caywg==
-----END PRIVATE KEY-----'''
data=b'{"login": "test-user","nonce": "98475920834"}'
signature=OpenSSL.crypto.sign(key,data,'sha512')
print (signature)
The error I get is
Traceback (most recent call last):
File "./jwt.py", line 37, in <module>
signatue=OpenSSL.crypto.sign(key,data,'sha512')
File "/usr/local/lib/python3.7/dist-packages/OpenSSL/crypto.py", line 2825, in sign
length = _lib.EVP_PKEY_size(pkey._pkey)
AttributeError: 'bytes' object has no attribute '_pkey'
What is going on here???
(p.s. the key is not valid for use anymore but should be still good to go for creating a singnature)
I did find a solution my self.
#!/usr/bin/env python3
from OpenSSL import crypto
import base64
key_file = open("test.pem", "r")
key = key_file.read()
key_file.close()
print(key)
print()
if key.startswith('-----BEGIN '):
pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, key)
else:
pkey = crypto.load_pkcs12(key).get_privatekey()
print (pkey)
print()
data = b'''{ "login": "usernam", "nonce": "98475920834" }'''
sign = crypto.sign(pkey, data, "sha512")
print (sign)
print()
data_base64 = base64.b64encode(sign)
print (data_base64.decode())
this works for me. :-)

Python xmlsec XML Signature Value mismatch

I am new to xml signatures and currently I am using xmlsec to generate a signed xml. I do this with some modifications on the sample code:
from lxml import etree
import xmlsec
parser = etree.XMLParser(remove_blank_text=True)
template = etree.parse('unsigned.xml', parser).getroot()
signature_node = xmlsec.tree.find_node(template, xmlsec.constants.NodeSignature)
ctx = xmlsec.SignatureContext()
key = xmlsec.Key.from_file('keys/private_key.pem', xmlsec.constants.KeyDataFormatPem)
ctx.key = key
sig_ = ctx.sign(signature_node)
formated = etree.tostring(template)
with open('signed_test.xml', 'wb') as the_file:
the_file.write(formated)
Now I have signed XML, and from here I am trying to learn where or how the values get generated. I am following this for context. I am able to verify the DigestValue and now I am trying to get the SignatureValue. From the link and some other questions here in stackoverflow, I just need to:
Canonized the whole SignedInfo element
Hash the result
Sign the Hash
In order to get the signature value. I am canonizing the SignedInfo Element using lxml:
from lxml import etree
parser = etree.XMLParser(remove_blank_text=True)
xmlTree = etree.parse('signed_info.xml', parser)
root = xmlTree.getroot()
formated = etree.tostring(root, method='c14n', exclusive=True)
# Write to file
with open('canon_sinfo.xml', 'wb') as the_file:
the_file.write(formated)
For info the following is the resulting SignedInfo:
<SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></SignatureMethod><Reference URI="#obj"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#base64"></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod><DigestValue>izbIdQ4tSAg6VKGpr1zd6kU9QpVQi/Bcwxjxu/k2oKk=</DigestValue></Reference></SignedInfo>
I am using cryptography to try and generate the SignatureValue however, I cannot get the same result as that of what xmlsec generated.
Here is my code snippet in doing so:
sign_info = '''String of the Sign Info'''
digest_sinfo = hashes.Hash(hashes.SHA256(), backend=default_backend())
digest_sinfo.update(bytes(sign_info, 'utf-8'))
digested_sinfo = digest_sinfo.finalize()
# Load private_key here...
# Sign the message
signature_1v15 = private_key.sign(
digested_sinfo,
padding.PKCS1v15(),
hashes.SHA256()
)
I also tried loading the SignedInfo into a seperate file, however I still get a mismatched SignatureValue. How do I accomplish this?
Your issue is that you do the hashing twice. The sign() function does the hashing for you so you can skip the middle part.
Just call the sign() with your canonized SignedInfo element:
signature_1v15 = private_key.sign(
sign_info,
padding.PKCS1v15(),
hashes.SHA256()
)

RSA OAEP Decryption in Python

I have a hex encoded string which I need to decrypt using RSA_OAEP algorithm.Below is my code snippet:
final_token = decoded_req['token']
print(final_token)
print("Converting actual token into bytes")
## Hex encoded string to bytes
token_to_bytes = bytes.fromhex(final_token)
print(token_to_bytes)
## Read the private key
with open('private.rsa', 'r') as pvt_key:
miPvt = pvt_key.read()
## Decrypt the token using RSA_OAEP
print("Decrypting the token")
rsakey_obj = RSA.importKey(miPvt)
cipher = PKCS1_OAEP.new(rsakey_obj)
dec_token = cipher.decrypt(token_to_bytes)
print(dec_token)
Below is the command line output:
6c79855ca15a3ac0308d17db97a1c576b6f35e4bb630da22867d0d081d55f05e1b1c640d7e7bd8c8de06b6a03e2ef7449e31fa9c0f0c675ebbf838bb880a4c6e309391441e1c41a0c42fbe11eaf6306bb39e7bbbffbe2dbced8c9bb07679ff18cef348b2b7ce08aa05028fda818ac4ce08ad84246c94afbcac405db5258c5333f66148007be8fa5384fa78a0d54ccf26028571180723b2a61fe18ebd0124f7e008902e79b48a53d29953ffde949878b4eb99d376ccf68341b0ec2ceb03b050e7c260f8905dccddb5e50cb331a3bb6bc034fc06dfaf722fd8fad8cb7a311b020be8b1a9115279173b18f46ccc0e28c71f0a6f67e8362a103fa4729057d8924ef0a6fb5a33eeb5b42cdc764fde53b9d6338472fc73e80cf785eb54ffb4ac15a6bf63db19baca586508b8160bf73dbad322221ddb632f5ae8040ef86805a408fc7df6f4a8ee5c7a444a5a13dbdcb8b958c52a8bdc4394e5deaabce203a3ff8675079e6618ac3558cdaf5ce6da77ca667bd5349ba82cc1ad3f71a662a2b7c8b47cc548209264a45a65b3f6f25fedcad8449699a19e2910d24c13b44e3e9445a62f88213346e00048480218996ade7e01151b7e038fbc8a5ff03bfa511126763d4571dec6ce0f5183302a99eee62facabe09211f3a61b8d154a38f0ee9a2647998e2ec1b8ee96b52c443f408cec24140838616c79d82cba4b77171b621f261539e239
Converting actual token into bytes
b'ly\x85\\\xa1Z:\xc00\x8d\x17\xdb\x97\xa1\xc5v\xb6\xf3^K\xb60\xda"\x86}\r\x08\x1dU\xf0^\x1b\x1cd\r~{\xd8\xc8\xde\x06\xb6\xa0>.\xf7D\x9e1\xfa\x9c\x0f\x0cg^\xbb\xf88\xbb\x88\nLn0\x93\x91D\x1e\x1cA\xa0\xc4/\xbe\x11\xea\xf60k\xb3\x9e{\xbb\xff\xbe-\xbc\xed\x8c\x9b\xb0vy\xff\x18\xce\xf3H\xb2\xb7\xce\x08\xaa\x05\x02\x8f\xda\x81\x8a\xc4\xce\x08\xad\x84$l\x94\xaf\xbc\xac#]\xb5%\x8cS3\xf6aH\x00{\xe8\xfaS\x84\xfax\xa0\xd5L\xcf&\x02\x85q\x18\x07#\xb2\xa6\x1f\xe1\x8e\xbd\x01$\xf7\xe0\x08\x90.y\xb4\x8aS\xd2\x99S\xff\xde\x94\x98x\xb4\xeb\x99\xd3v\xcc\xf6\x83A\xb0\xec,\xeb\x03\xb0P\xe7\xc2`\xf8\x90]\xcc\xdd\xb5\xe5\x0c\xb31\xa3\xbbk\xc04\xfc\x06\xdf\xafr/\xd8\xfa\xd8\xcbz1\x1b\x02\x0b\xe8\xb1\xa9\x11Ry\x17;\x18\xf4l\xcc\x0e(\xc7\x1f\nog\xe86*\x10?\xa4r\x90W\xd8\x92N\xf0\xa6\xfbZ3\xee\xb5\xb4,\xdcvO\xdeS\xb9\xd63\x84r\xfcs\xe8\x0c\xf7\x85\xebT\xff\xb4\xac\x15\xa6\xbfc\xdb\x19\xba\xcaXe\x08\xb8\x16\x0b\xf7=\xba\xd3""\x1d\xdbc/Z\xe8\x04\x0e\xf8h\x05\xa4\x08\xfc}\xf6\xf4\xa8\xee\\zDJZ\x13\xdb\xdc\xb8\xb9X\xc5*\x8b\xdcC\x94\xe5\xde\xaa\xbc\xe2\x03\xa3\xff\x86u\x07\x9ef\x18\xac5X\xcd\xaf\\\xe6\xdaw\xcaf{\xd54\x9b\xa8,\xc1\xad?q\xa6b\xa2\xb7\xc8\xb4|\xc5H \x92d\xa4Ze\xb3\xf6\xf2_\xed\xca\xd8D\x96\x99\xa1\x9e)\x10\xd2L\x13\xb4N>\x94E\xa6/\x88!3F\xe0\x00HH\x02\x18\x99j\xde~\x01\x15\x1b~\x03\x8f\xbc\x8a_\xf0;\xfaQ\x11&v=Eq\xde\xc6\xce\x0fQ\x830*\x99\xee\xe6/\xac\xab\xe0\x92\x11\xf3\xa6\x1b\x8d\x15J8\xf0\xee\x9a&G\x99\x8e.\xc1\xb8\xee\x96\xb5,D?#\x8c\xec$\x14\x088aly\xd8,\xbaKw\x17\x1bb\x1f&\x159\xe29'
Decrypting the token
Traceback (most recent call last):
File "script.py", line 80, in <module>
dec_token = cipher.decrypt(token_to_bytes)
File "/home/venv/lib/python3.6/site-packages/Crypto/Cipher/PKCS1_OAEP.py", line 201, in decrypt
raise ValueError("Incorrect decryption.")
ValueError: Incorrect decryption.
Can someone help me in resolving this issue?
I suspect you have not correctly transferred your encrypted token. But there isn't a lot to go on.
I've used you example code though to help me write the below which does seem to work, (thank you for that) or at least it decrypted a value from another implementation.
In my case it was a node JS implementation
var nodeRsa = require("node-rsa");
const key = new nodeRsa( "-----BEGIN PUBLIC KEY-----\n\
.
.
.
-----END PUBLIC KEY-----");
key.encrypt("passwd","base64");
If I took the output of the above and put in a file called 'ciphertext', this following python decrypts the message correctly.
import Crypto.Cipher.PKCS1_OAEP as rsaenc
import Crypto.PublicKey.RSA as RSA
import codecs
## Load the private key and the base 64 ciphertext.
with open("key.pem") as f:
keystring = f.read()
with open("ciphertext","rb") as f:
base64msg = f.read()
# Create the binary ciphertext
binmsg=codecs.decode(base64msg,'base64')
# Setup the RSA objetcs
k = RSA.importKey(keystring)
cipher = rsaenc.new(k)
plaintext = cipher.decrypt(binmsg)
print (plaintext)

Resources