Decode text encoded with RSA - python

I have a RSA public/private key pair and passphrase. I am trying to decode text encrypted using using above key(s). The encoded text is always 512 chars long alpha-num string.
I have tried using the code provided at SOF question Decrypt using an RSA public key with PyCrypto
First I used my private key which was encoded with AES-256-CBC from a PEM file.
This is start of privkey.pem which made me think its AES-256 encrypted
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC
<rest of the data>
-----END RSA PRIVATE KEY-----
but I received following error message.
ValueError: PEM encryption format not supported.
So I asked the source for a private key without AES encryption which they gave me. Now using this key the decrypted works and the decrypted text looks like below (I am only showing some of the text)
b'\x93\n(\x92\x02\x9aF*?\x18"\x19\x12Gn\xc2\<rest of the text>'
This is not my plain text. What am I doing wrong? can someone help me to decode this text.
EDIT 1:
Based on Maarten's answer below, I have tried the following code but I am still getting errors.
Here is my code for decryption
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
import ast
encrypted_text = "39085fc25e<HIDDEN>2fcce845760391ff"
key = RSA.importKey(open("\\path_to_key\\private.der", encoding="utf8").read())
cipher = PKCS1_OAEP.new(key)
message = cipher.decrypt(ast.literal_eval(str(uid)))
and I get error:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 1: invalid start byte
Note that I had to convert my private key from PEM to DER using the code below becasue using PEM file I was getting SyntaxError: unexpected EOF while parsing
openssl rsa -in private_key.pem -out private_key.der -outform DER
becasue

Here is the solution that I have found.
First of all I am using pycryptodome librray instead of pycrypto.
Below are my encode and decode functions.
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
def encode_rsa(message, key_path):
key = RSA.importKey(open(key_path).read())
cipher = PKCS1_OAEP.new(key)
ciphertext = cipher.encrypt(message)
return ciphertext
def decode_rsa(ciphertext, key_path):
key = RSA.importKey(open(key_path).read())
cipher = PKCS1_OAEP.new(key)
# before decrypt convert the hex string to byte_array
message = cipher.decrypt(bytearray.fromhex(ciphertext))
return message
Using above two functions I was able to encode/deode the data correctly.

Related

Generate JWT token signed with RSA key in python

I am trying to convert this java code for generating JWT token in python.
String privateKeyContent = privateKey
.replaceAll(Definitions.ApiGeneral.LINE_BREAKER, "")
.replace(Definitions.AuthProperty.PRIVATE_KEY_START, "")
.replace(Definitions.AuthProperty.PRIVATE_KEY_END, "");
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));
KeyFactory kf = KeyFactory.getInstance(Definitions.AuthProperty.RSA_KEY_FACTORY);
PrivateKey privKey = kf.generatePrivate(keySpecPKCS8);
String jwtAudUrl = System.getenv(Definitions.IamProperty.IAM_URL_KEY) + System.getenv(Definitions.IamProperty.JWT_AUD_URI_KEY);
String jwtToken = Jwts.builder()
.setAudience(jwtAudUrl)
.setSubject(serviceId)
.setIssuer(serviceId)
.setExpiration(new Date(new Date().getTime() + TimeUnit.MINUTES.toMillis(Definitions.AuthProperty.JWT_TOKEN_EXPIRY_IN_MINUTES)))
.signWith(privKey)
.compact();
Python:
import jwt
serviceID = "abc"
secret = '-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCAQEAhstYtRbkgQkFwlVr8QjSCQqqRTDMKWHdIGRYBpXcQmvKfagId9nBA2Ygh7cOrT9g8MhxYo8U1jYmPQpv6gf3LgO/J0qspLdaAhZP6LusA/HHJBR7kjTXBsLcsEDyd8S0UioBYP3DLvtWhGIR2f4o7SH1TlE96tldV6FZKGO2NHsJrJwTd+ym0AeZe0b7QZLe43LBCTLdqk05U34jrknJliSAEbGqYg4h6nrJsKBC/0pmiQ9ptD1N/Kl4bqffMWIbZq2bPP6jFrmBLe+7yTeVMKltVbJZys4nHhyYngBtbAxynXeB2tpE8If7cK75fj42MlFgquEiEZZVSzNNmrmPOwIDAQABAoH/B18Xes/Fr0jPB9GkFYpl8hijNyV0BM9VSHA0YCfR49ABQt3tmKBP7d+n58QbCV5t7r0Hdlxcx1ouvSfU9vd4jQunaH6s8lUUlwihVhjtT0npmg+EsnoxSC1f5EOo/uPC+LtTV/qIsgkMsjCqyUEc+9rfj2jh+fXpJOGt/od1b2k2xs84MsXmSF/As7GYRdw+FLbkN64R/SGmv3NLtQdg5uvBKLuKvtQWIJBuPqgKOsJWaCVO0XaoUDQeav/nTfP0ntmF0QH9JtXYzBldhGq2FPVQRUaCuJ4YPEpXlD3FptQBlX/Wu7wXbdwDz3qyXbGqSkiaR3gN+QR+IgjG3oQxAoGBAML5M4Dg0S/yobHuCRcvpngraXGBWnCTaD0mMh/cosV0HBNdZbglwVpG8Agz9BEYIrDM777HFuB+lWUvGNMR45rObPcDqn7Qj8Uwnj775Bg0Sx09MCBds6IGce/92uPUsHPx4pj8dzCj1s3cfUKO+EaUE33bnFXcMCGh/0x0sIVXAoGBALD8H4Aph2OPQK9OOHb3ULDvrmMPrpe3xv5iSzfLt7xBIP2G0Wl+q0hzEtdEOUZGQemOtyuV5t9Jwwfh9uH9jAhk9OEvoNg3F3mQl6hjmHPd1xUNvRTqwnV+VvQnw7Aeq2TZMcAKwbXf3+p430wMsxR6m0Y7rGi0FIxWbILp0RK9AoGBAIfiPBXnGYOsOysRtb42FHQN9WgI+eoZof10IFz6XWr12Bda8Wicz5vGcsWUx9YeFxdXTQOOJ5CASEiDwW5hOlqK4YBqSqolWv3YO4Gz9i00TOFs4py8EVSr3z6ekq5UbkHwY7exxLPei/dfYuE/WSN/UfJWWyev1M+r4oz7iobzAoGAKe8S56LvWT+P6/l0l3txuvqPLxmAHKKGm69ecxHprskfr/JJm91PaBMb27VmfKgY5eXSsJkL4svvUebQQCt7CmIhQ1mtmo0zGrKPvG4cqRde5rYintogyQXuRFtHmmsp4PM1PnNOAnHQ9BU/kx1PMQL712A8MXK5i6bOfxY3W2ECgYEAp9cw3NeMSy/WcXyZoyNFUdEQiHTJGPBtELjHWRnjMU1454EkWYYPiYXUnElfxP6InxHgMNbGVsd1BUEhXOdSUS5bO/WBOOPqSh6MIGfKFuMN/9SI/Y/UZKltCD1CboTvDfmkD+opkLM6YZpW9CRT7Szn7ivdFr5KqGQZUZOwn3k=-----END RSA PRIVATE KEY-----'
due_date = datetime.now() + timedelta(minutes=10)
header = {"alg": "RS256"}
expiry = int(due_date.timestamp())
payload = {"iss": serviceID, "sub": serviceID, "exp": expiry, "aud": iam_url + "/oauth2/access_token"}
priv_rsakey = serialization.load_pem_private_key(secret.encode('utf8'), password=None, backend=default_backend())
token=jwt.encode(payload, priv_rsakey, algorithm='RS256')
However, I keep on getting this error :
ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=503841036, lib=60, reason=524556, reason_text=b'error:1E08010C:DECODER routines::unsupported')])
Can someone please help me with this ?
The issue is precisely identified in the error message: Your private key is incorrectly formatted. A PEM encoded key consists of the Base64 encoded body, which contains a line break after every 64 characters, and a header and footer on separate lines. Your key is missing the line breaks.
load_pem_private_key() expects at least header and footer on separate lines, but is tolerant about line breaks in the body, i.e. they are optional. So you have to pass your key e.g. like this:
secret = '-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAhstYtRbkgQkFwlVr8QjSCQqqRTDMKWHdIGRYBpXcQmvKfagId9nBA2Ygh7cOrT9g8MhxYo8U1jYmPQpv6gf3LgO/J0qspLdaAhZP6LusA/HHJBR7kjTXBsLcsEDyd8S0UioBYP3DLvtWhGIR2f4o7SH1TlE96tldV6FZKGO2NHsJrJwTd+ym0AeZe0b7QZLe43LBCTLdqk05U34jrknJliSAEbGqYg4h6nrJsKBC/0pmiQ9ptD1N/Kl4bqffMWIbZq2bPP6jFrmBLe+7yTeVMKltVbJZys4nHhyYngBtbAxynXeB2tpE8If7cK75fj42MlFgquEiEZZVSzNNmrmPOwIDAQABAoH/B18Xes/Fr0jPB9GkFYpl8hijNyV0BM9VSHA0YCfR49ABQt3tmKBP7d+n58QbCV5t7r0Hdlxcx1ouvSfU9vd4jQunaH6s8lUUlwihVhjtT0npmg+EsnoxSC1f5EOo/uPC+LtTV/qIsgkMsjCqyUEc+9rfj2jh+fXpJOGt/od1b2k2xs84MsXmSF/As7GYRdw+FLbkN64R/SGmv3NLtQdg5uvBKLuKvtQWIJBuPqgKOsJWaCVO0XaoUDQeav/nTfP0ntmF0QH9JtXYzBldhGq2FPVQRUaCuJ4YPEpXlD3FptQBlX/Wu7wXbdwDz3qyXbGqSkiaR3gN+QR+IgjG3oQxAoGBAML5M4Dg0S/yobHuCRcvpngraXGBWnCTaD0mMh/cosV0HBNdZbglwVpG8Agz9BEYIrDM777HFuB+lWUvGNMR45rObPcDqn7Qj8Uwnj775Bg0Sx09MCBds6IGce/92uPUsHPx4pj8dzCj1s3cfUKO+EaUE33bnFXcMCGh/0x0sIVXAoGBALD8H4Aph2OPQK9OOHb3ULDvrmMPrpe3xv5iSzfLt7xBIP2G0Wl+q0hzEtdEOUZGQemOtyuV5t9Jwwfh9uH9jAhk9OEvoNg3F3mQl6hjmHPd1xUNvRTqwnV+VvQnw7Aeq2TZMcAKwbXf3+p430wMsxR6m0Y7rGi0FIxWbILp0RK9AoGBAIfiPBXnGYOsOysRtb42FHQN9WgI+eoZof10IFz6XWr12Bda8Wicz5vGcsWUx9YeFxdXTQOOJ5CASEiDwW5hOlqK4YBqSqolWv3YO4Gz9i00TOFs4py8EVSr3z6ekq5UbkHwY7exxLPei/dfYuE/WSN/UfJWWyev1M+r4oz7iobzAoGAKe8S56LvWT+P6/l0l3txuvqPLxmAHKKGm69ecxHprskfr/JJm91PaBMb27VmfKgY5eXSsJkL4svvUebQQCt7CmIhQ1mtmo0zGrKPvG4cqRde5rYintogyQXuRFtHmmsp4PM1PnNOAnHQ9BU/kx1PMQL712A8MXK5i6bOfxY3W2ECgYEAp9cw3NeMSy/WcXyZoyNFUdEQiHTJGPBtELjHWRnjMU1454EkWYYPiYXUnElfxP6InxHgMNbGVsd1BUEhXOdSUS5bO/WBOOPqSh6MIGfKFuMN/9SI/Y/UZKltCD1CboTvDfmkD+opkLM6YZpW9CRT7Szn7ivdFr5KqGQZUZOwn3k=\n-----END RSA PRIVATE KEY-----'
or
secret = '''-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAhstYtRbkgQkFwlVr8QjSCQqqRTDMKWHdIGRYBpXcQmvKfagId9nBA2Ygh7cOrT9g8MhxYo8U1jYmPQpv6gf3LgO/J0qspLdaAhZP6LusA/HHJBR7kjTXBsLcsEDyd8S0UioBYP3DLvtWhGIR2f4o7SH1TlE96tldV6FZKGO2NHsJrJwTd+ym0AeZe0b7QZLe43LBCTLdqk05U34jrknJliSAEbGqYg4h6nrJsKBC/0pmiQ9ptD1N/Kl4bqffMWIbZq2bPP6jFrmBLe+7yTeVMKltVbJZys4nHhyYngBtbAxynXeB2tpE8If7cK75fj42MlFgquEiEZZVSzNNmrmPOwIDAQABAoH/B18Xes/Fr0jPB9GkFYpl8hijNyV0BM9VSHA0YCfR49ABQt3tmKBP7d+n58QbCV5t7r0Hdlxcx1ouvSfU9vd4jQunaH6s8lUUlwihVhjtT0npmg+EsnoxSC1f5EOo/uPC+LtTV/qIsgkMsjCqyUEc+9rfj2jh+fXpJOGt/od1b2k2xs84MsXmSF/As7GYRdw+FLbkN64R/SGmv3NLtQdg5uvBKLuKvtQWIJBuPqgKOsJWaCVO0XaoUDQeav/nTfP0ntmF0QH9JtXYzBldhGq2FPVQRUaCuJ4YPEpXlD3FptQBlX/Wu7wXbdwDz3qyXbGqSkiaR3gN+QR+IgjG3oQxAoGBAML5M4Dg0S/yobHuCRcvpngraXGBWnCTaD0mMh/cosV0HBNdZbglwVpG8Agz9BEYIrDM777HFuB+lWUvGNMR45rObPcDqn7Qj8Uwnj775Bg0Sx09MCBds6IGce/92uPUsHPx4pj8dzCj1s3cfUKO+EaUE33bnFXcMCGh/0x0sIVXAoGBALD8H4Aph2OPQK9OOHb3ULDvrmMPrpe3xv5iSzfLt7xBIP2G0Wl+q0hzEtdEOUZGQemOtyuV5t9Jwwfh9uH9jAhk9OEvoNg3F3mQl6hjmHPd1xUNvRTqwnV+VvQnw7Aeq2TZMcAKwbXf3+p430wMsxR6m0Y7rGi0FIxWbILp0RK9AoGBAIfiPBXnGYOsOysRtb42FHQN9WgI+eoZof10IFz6XWr12Bda8Wicz5vGcsWUx9YeFxdXTQOOJ5CASEiDwW5hOlqK4YBqSqolWv3YO4Gz9i00TOFs4py8EVSr3z6ekq5UbkHwY7exxLPei/dfYuE/WSN/UfJWWyev1M+r4oz7iobzAoGAKe8S56LvWT+P6/l0l3txuvqPLxmAHKKGm69ecxHprskfr/JJm91PaBMb27VmfKgY5eXSsJkL4svvUebQQCt7CmIhQ1mtmo0zGrKPvG4cqRde5rYintogyQXuRFtHmmsp4PM1PnNOAnHQ9BU/kx1PMQL712A8MXK5i6bOfxY3W2ECgYEAp9cw3NeMSy/WcXyZoyNFUdEQiHTJGPBtELjHWRnjMU1454EkWYYPiYXUnElfxP6InxHgMNbGVsd1BUEhXOdSUS5bO/WBOOPqSh6MIGfKFuMN/9SI/Y/UZKltCD1CboTvDfmkD+opkLM6YZpW9CRT7Szn7ivdFr5KqGQZUZOwn3k=
-----END RSA PRIVATE KEY-----'''
With this change the code works (after adding the missing iam_url and the missing import statements).
Note that PKCS8EncodedKeySpec in the Java code expects a DER encoded private key in PKCS#8 format, while in the Python code a PEM encoded private key in PKCS#1 format is applied.
A DER encoded key results from a PEM encoded key by removing header, footer and all line breaks, and Base64 decoding the rest. The Cryptography library supports the import of a DER encoded private key with load_der_private_key():
import base64
secret = base64.b64decode('MIIEogIBAAKCAQEAhstYtRbkgQkFwlVr8QjSCQqqRTDMKWHdIGRYBpXcQmvKfagId9nBA2Ygh7cOrT9g8MhxYo8U1jYmPQpv6gf3LgO/J0qspLdaAhZP6LusA/HHJBR7kjTXBsLcsEDyd8S0UioBYP3DLvtWhGIR2f4o7SH1TlE96tldV6FZKGO2NHsJrJwTd+ym0AeZe0b7QZLe43LBCTLdqk05U34jrknJliSAEbGqYg4h6nrJsKBC/0pmiQ9ptD1N/Kl4bqffMWIbZq2bPP6jFrmBLe+7yTeVMKltVbJZys4nHhyYngBtbAxynXeB2tpE8If7cK75fj42MlFgquEiEZZVSzNNmrmPOwIDAQABAoH/B18Xes/Fr0jPB9GkFYpl8hijNyV0BM9VSHA0YCfR49ABQt3tmKBP7d+n58QbCV5t7r0Hdlxcx1ouvSfU9vd4jQunaH6s8lUUlwihVhjtT0npmg+EsnoxSC1f5EOo/uPC+LtTV/qIsgkMsjCqyUEc+9rfj2jh+fXpJOGt/od1b2k2xs84MsXmSF/As7GYRdw+FLbkN64R/SGmv3NLtQdg5uvBKLuKvtQWIJBuPqgKOsJWaCVO0XaoUDQeav/nTfP0ntmF0QH9JtXYzBldhGq2FPVQRUaCuJ4YPEpXlD3FptQBlX/Wu7wXbdwDz3qyXbGqSkiaR3gN+QR+IgjG3oQxAoGBAML5M4Dg0S/yobHuCRcvpngraXGBWnCTaD0mMh/cosV0HBNdZbglwVpG8Agz9BEYIrDM777HFuB+lWUvGNMR45rObPcDqn7Qj8Uwnj775Bg0Sx09MCBds6IGce/92uPUsHPx4pj8dzCj1s3cfUKO+EaUE33bnFXcMCGh/0x0sIVXAoGBALD8H4Aph2OPQK9OOHb3ULDvrmMPrpe3xv5iSzfLt7xBIP2G0Wl+q0hzEtdEOUZGQemOtyuV5t9Jwwfh9uH9jAhk9OEvoNg3F3mQl6hjmHPd1xUNvRTqwnV+VvQnw7Aeq2TZMcAKwbXf3+p430wMsxR6m0Y7rGi0FIxWbILp0RK9AoGBAIfiPBXnGYOsOysRtb42FHQN9WgI+eoZof10IFz6XWr12Bda8Wicz5vGcsWUx9YeFxdXTQOOJ5CASEiDwW5hOlqK4YBqSqolWv3YO4Gz9i00TOFs4py8EVSr3z6ekq5UbkHwY7exxLPei/dfYuE/WSN/UfJWWyev1M+r4oz7iobzAoGAKe8S56LvWT+P6/l0l3txuvqPLxmAHKKGm69ecxHprskfr/JJm91PaBMb27VmfKgY5eXSsJkL4svvUebQQCt7CmIhQ1mtmo0zGrKPvG4cqRde5rYintogyQXuRFtHmmsp4PM1PnNOAnHQ9BU/kx1PMQL712A8MXK5i6bOfxY3W2ECgYEAp9cw3NeMSy/WcXyZoyNFUdEQiHTJGPBtELjHWRnjMU1454EkWYYPiYXUnElfxP6InxHgMNbGVsd1BUEhXOdSUS5bO/WBOOPqSh6MIGfKFuMN/9SI/Y/UZKltCD1CboTvDfmkD+opkLM6YZpW9CRT7Szn7ivdFr5KqGQZUZOwn3k=')
priv_rsakey = serialization.load_der_private_key(secret, password=None, backend=default_backend())
load_pem_private_key() and load_der_private_key() support both PKCS#8 and PKCS#1 format.

How do I take the user input as it is given and not have it converted to the string data type?

I have a key
b'-----BEGIN RSA PRIVATE KEY-----\nMIIDCgIBAAKBpwYMzwEMAwLajdq74D0Q7NRXICJr/EZHI6z0NcmVbiAj139f7apO\nWG0KV9MJVjENFkh1Ld64B2GY8Ibq7/jCz/nPU67eQPmAKU59COzGK0+WSiDJ+twE\nLwH0eqzvC6DauDngw2biWIR6p/A9OHFXm2xANW1CPq64a/h9IFlXslOhHtwjfv8k\nN0mZ/PHK9vxWJlWwxEmI/sBXJlAa1fxxCl62H2N4YIvrAgMBAAECgacCOSrJY7Sn\nk9GVlH1vc4zU67+vZqeq2/HMWWJ61iNGRGWpNYONloUAbVChCUlXdUu/DPDybAaq\nYx3hNu1BKbZsQziphpuyFNsZMPHasWixMrXDHvTWUcEuOYKjk4EksDsCplo1BryY\n+O6kel711Xi6zVXEt/1aWc8s6KP1sIPunSbUh4m9BIPQzrQ6ImdgY0XtSqpIvw2I\n2zPFnRb2ZsMx7KgnXt1VlzX2g=\n-----END RSA PRIVATE KEY-----'
I need to take this as an input
key = input("enter your key")
When I do this, the key is converted to a string.
"b'-----BEGIN RSA PRIVATE KEY-----\nMIIDCgIBAAKBpwYMzwEMAwLajdq74D0Q7NRXICJr/EZHI6z0NcmVbiAj139f7apO\nWG0KV9MJVjENFkh1Ld64B2GY8Ibq7/jCz/nPU67eQPmAKU59COzGK0+WSiDJ+twE\nLwH0eqzvC6DauDngw2biWIR6p/A9OHFXm2xANW1CPq64a/h9IFlXslOhHtwjfv8k\nN0mZ/PHK9vxWJlWwxEmI/sBXJlAa1fxxCl62H2N4YIvrAgMBAAECgacCOSrJY7Sn\nk9GVlH1vc4zU67+vZqeq2/HMWWJ61iNGRGWpNYONloUAbVChCUlXdUu/DPDybAaq\nYx3hNu1BKbZsQziphpuyFNsZMPHasWixMrXDHvTWUcEuOYKjk4EksDsCplo1BryY\n+O6kel711Xi6zVXEt/1aWc8s6KP1sIPunSbUh4m9BIPQzrQ6ImdgY0XtSqpIvw2I\n2zPFnRb2ZsMx7KgnXt1VlzX2g=\n-----END RSA PRIVATE KEY-----'"
Because of this I cannot use it for the purpose the key was created.
If I encode this key, the result becomes:
b"b'-----BEGIN RSA PRIVATE KEY-----\nMIIDCgIBAAKBpwYMzwEMAwLajdq74D0Q7NRXICJr/EZHI6z0NcmVbiAj139f7apO\nWG0KV9MJVjENFkh1Ld64B2GY8Ibq7/jCz/nPU67eQPmAKU59COzGK0+WSiDJ+twE\nLwH0eqzvC6DauDngw2biWIR6p/A9OHFXm2xANW1CPq64a/h9IFlXslOhHtwjfv8k\nN0mZ/PHK9vxWJlWwxEmI/sBXJlAa1fxxCl62H2N4YIvrAgMBAAECgacCOSrJY7Sn\nk9GVlH1vc4zU67+vZqeq2/HMWWJ61iNGRGWpNYONloUAbVChCUlXdUu/DPDybAaq\nYx3hNu1BKbZsQziphpuyFNsZMPHasWixMrXDHvTWUcEuOYKjk4EksDsCplo1BryY\n+O6kel711Xi6zVXEt/1aWc8s6KP1sIPunSbUh4m9BIPQzrQ6ImdgY0XtSqpIvw2I\n2zPFnRb2ZsMx7KgnXt1VlzX2g=\n-----END RSA PRIVATE KEY-----'"
Therefore I still cannot use it.
How do I take the input as bytes??
This is not an elegant answer but reading an RSA key from stdin isn't either so... As someone suggested in the comments, you should probably read it from a file. It would be cleaner, but hey you asked for stdin, so here is a stdin-based answer :
#!/usr/bin/python3
from sys import stdin
private_key = ""
for line in stdin:
private_key += line
# We need a stopping condition otherwise it will read from stdin forever
if "END RSA PRIVATE KEY" in line:
break
# We must validate what has been entered is correct (a regex would be better)
if not private_key.startswith("-----BEGIN RSA PRIVATE KEY-----"):
raise Exception("Invalid private key !")
print("Here is your private key :")
print(private_key)
Enter the key as is, not on one line, and as said in other answers, don't include b'' in your input :
$ python3 test.py
-----BEGIN RSA PRIVATE KEY-----
MIIDCgIBAAKBpwYMzwEMAwLajdq74D0Q7NRXICJr/EZHI6z0NcmVbiAj139f7apO
WG0KV9MJVjENFkh1Ld64B2GY8Ibq7/jCz/nPU67eQPmAKU59COzGK0+WSiDJ+twE
LwH0eqzvC6DauDngw2biWIR6p/A9OHFXm2xANW1CPq64a/h9IFlXslOhHtwjfv8k
N0mZ/PHK9vxWJlWwxEmI/sBXJlAa1fxxCl62H2N4YIvrAgMBAAECgacCOSrJY7Sn
k9GVlH1vc4zU67+vZqeq2/HMWWJ61iNGRGWpNYONloUAbVChCUlXdUu/DPDybAaq
Yx3hNu1BKbZsQziphpuyFNsZMPHasWixMrXDHvTWUcEuOYKjk4EksDsCplo1BryY
+O6kel711Xi6zVXEt/1aWc8s6KP1sIPunSbUh4m9BIPQzrQ6ImdgY0XtSqpIvw2I
2zPFnRb2ZsMx7KgnXt1VlzX2g=
-----END RSA PRIVATE KEY-----
Here is your private key :
-----BEGIN RSA PRIVATE KEY-----
MIIDCgIBAAKBpwYMzwEMAwLajdq74D0Q7NRXICJr/EZHI6z0NcmVbiAj139f7apO
WG0KV9MJVjENFkh1Ld64B2GY8Ibq7/jCz/nPU67eQPmAKU59COzGK0+WSiDJ+twE
LwH0eqzvC6DauDngw2biWIR6p/A9OHFXm2xANW1CPq64a/h9IFlXslOhHtwjfv8k
N0mZ/PHK9vxWJlWwxEmI/sBXJlAa1fxxCl62H2N4YIvrAgMBAAECgacCOSrJY7Sn
k9GVlH1vc4zU67+vZqeq2/HMWWJ61iNGRGWpNYONloUAbVChCUlXdUu/DPDybAaq
Yx3hNu1BKbZsQziphpuyFNsZMPHasWixMrXDHvTWUcEuOYKjk4EksDsCplo1BryY
+O6kel711Xi6zVXEt/1aWc8s6KP1sIPunSbUh4m9BIPQzrQ6ImdgY0XtSqpIvw2I
2zPFnRb2ZsMx7KgnXt1VlzX2g=
-----END RSA PRIVATE KEY-----
Edit as ShellCode said since key stream already contain new line characters this will make input to return prematurely so you have to either keep reading until end of key stream which means at -----END RSA PRIVATE KEY----- or read this key directly from a file.
key = ""
print("Enter your key: ")
while True:
key += input()
if "-----END RSA PRIVATE KEY-----" in key:
break
key_bytes = bytes(key, encoding="ascii")
this way you can paste whole key without problems. Also when you enter your key dont enter as b'-----BEGIN RSA PRIVATE (rest of key) instead just enter key directly without b' at beginning and ' at end of key(only enter the key data) like -----BEGIN RSA PRIVATE (rest of key). So whole key will be
-----BEGIN RSA PRIVATE KEY-----\nMIIDCgIBAAKBpwYMzwEMAwLajdq74D0Q7NRXICJr/EZHI6z0NcmVbiAj139f7apO\nWG0KV9MJVjENFkh1Ld64B2GY8Ibq7/jCz/nPU67eQPmAKU59COzGK0+WSiDJ+twE\nLwH0eqzvC6DauDngw2biWIR6p/A9OHFXm2xANW1CPq64a/h9IFlXslOhHtwjfv8k\nN0mZ/PHK9vxWJlWwxEmI/sBXJlAa1fxxCl62H2N4YIvrAgMBAAECgacCOSrJY7Sn\nk9GVlH1vc4zU67+vZqeq2/HMWWJ61iNGRGWpNYONloUAbVChCUlXdUu/DPDybAaq\nYx3hNu1BKbZsQziphpuyFNsZMPHasWixMrXDHvTWUcEuOYKjk4EksDsCplo1BryY\n+O6kel711Xi6zVXEt/1aWc8s6KP1sIPunSbUh4m9BIPQzrQ6ImdgY0XtSqpIvw2I\n2zPFnRb2ZsMx7KgnXt1VlzX2g=\n-----END RSA PRIVATE KEY-----

RSA Encryption using the user-defined keys in python

I am trying to encrypt a small amount of data using RSA algorithm using python. The problem is I have the public and private RSA key. Both are stored in .pem and .ppk respectively. I am not able to find any help in google which will help me encrypt it using my keys. All the code and examples I saw generates its own keys. Is there a way where I can use my own keys to encrypt and decrypt the data?
You can use the rsa module .
import rsa
with open('public.ppm','r') as key_pub_file:
key_pub = key_pub_file.read()
message = "hello".encode('utf8')
enc_msg = rsa.encrypt(message, key_pub)
print(enc_msg)
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5
from base64 import b64decode,b64encode
f1 = open('public.ppm','r')
pubkey = f1.read()
#pubkey = 'MIGfMA0GCSqGSIb3DQEBA3UAWE0HSQ77CwP/8UbX07W2XKwng/nMT1R7vaz+2EeNR/FitFXwIDAQAB'
msg = "test"
keyDER = b64decode(pubkey)
keyPub = RSA.importKey(keyDER)
cipher = Cipher_PKCS1_v1_5.new(keyPub)
cipher_text = cipher.encrypt(msg.encode())
emsg = b64encode(cipher_text)
print(emsg)
While trying, I found this code to be working. msg variable contains the data to be encrypted and pubkey contains the public key which ill be taking from ppm file.

Python rsa module troubles

I need to encrypt some data, so I decided to use rsa module. I need to generate public and private keys. I want to send my public keys to some clients. How can I do this?
import rsa
(public_key, private_key) = rsa.newkeys(512)
So I've already generated it, but public_key now is a structure with two fields e and n. how can I transform it into bytes? And back from bytes to such structure?
You can use PyCrypto module
from Crypto.PublicKey import RSA
key = RSA.generate(512)
private_key = key.exportKey(passphrase='', pkcs=8)
public_key = key.publickey().exportKey()
In your case, try using save_pkcs1 method for saving into PEM format.
UPD:
Code sample for encrypt using rsa:
message = b'message'
# Alternative way - message = 'message'.encode('utf-8')
encrypted = rsa.encrypt(message, public_key)
For decrypt:
rsa.decrypt(encrypted, private_key).decode('utf-8')

Why signing data with RSA private key raise RSA key format is not supported in python?

I have a method as below that sign provided data:
def sign_data(self, private_key_loc, data):
"""
param: private_key_loc Path to your private key
param: package Data to be signed
return: base64 encoded signature
"""
key = open(private_key_loc, "r").read()
print(key)
rsakey = RSA.importKey(key) # This raise an error!!!!
print(rsakey)
signer = PKCS1_v1_5.new(rsakey)
digest = SHA256.new()
# It's being assumed the data is base64 encoded, so it's decoded before updating the digest
digest.update(data)
sign = signer.sign(digest)
return b64encode(sign)
The format of the private key is as below:
<RSAKeyValue><Modulus>nEWZmLeK0zgEWysFFcpcT6lnYpzYcXFf+r43wD73ko+CjR5EmwDsmlKqKS5y3rpIHQrj+xE+yiNGlcPFNwFl3cCcHPkeI0hqaPPYxE2XeP6Wa0keegny2AWWK2Cuv61YHVz4XgxTPBX7B/19ClN4wzI5CoNc9jkx0PIXEo5iWLk=</Modulus><Exponent>AQAB</Exponent><P>0b5D6oI3mOKKIHgfCrl03vfUTo91UeJyvpZ1l6F6NzUzPDhCG3Sin5dXtxEFejPayLsgLOIMMuqobOzI9wJpBQ==</P><Q>vrxvorDFE3g1cj2kWWWZc2BS7UMf+xxnPhtBR3x3T/DyTEnkEXvGLdRBuUGWKhxUpRcBkcBfAadJjhYUqYBvJQ==</Q><DP>SKYKiDPKZh4xkcWJmwFZxdE5rGxsSoyRCgq7eGXqGy1GLdmerDveCEE3lKVErGtBoL2QC3vQleJJrFDn2wbusQ==</DP><DQ>sIoTPd8lmd6ygVnCq6fZPywRtV9i03a3rIlng3YVrN1UNv5RZUlN5g9HAeRNzA5K3j8MCc6nYQ1ojGWtnDGvLQ==</DQ><InverseQ>rQzqbkXZ9Tmno3ElcliX57Xv4AXyF6yFO1kH4LHwkc8jN5dB9XYEdBIgm43yHFIznvOdc2L9Nkl2nHbFCeAKmg==</InverseQ><D>XA7IN+XP2zPBpS9HlJmcHbWO2NHK07FVODH8R70QPP9bieRNx/4YY6TU5uOc+cZFGw7CVLHJCm0TdMBaGlgxeC/GTwMrCJigxUgaxbvDmxuSpqYqkjoZhgoZAuUct8RaZUN8zNdEsXCqRhbU61U2Ey587RyPQ7varg9hkPicVHE=</D></RSAKeyValue>
NOTE: PRIVATE KEY IS FOR TEST NOTHING VALUEABLE
It seems that it is created in XML format.
In the line RSA.importKey(key) the error is raised as below:
ValueError: RSA key format is not supported
How should I feed that private key to sign data?
I even tried to form RSA key by parsing the XML and do something as the following:
rsakey = Crypto.PublicKey.RSA.construct((root.find('Modulus').text, root.find('Exponent').text,root.find('D').text))
It gives an error like:
assert isinstance(n, long)
AssertionError
RSA needs PEM file format in order to sign data. As my private key was not important! I used an online site to convert XML to PEM (DON'T DO THIS ON REAL PRIVATE KEYS :|). It now works.
My PEM file is now as below:
-----BEGIN RSA PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJxFmZi3itM4BFsr
BRXKXE+pZ2Kc2HFxX/q+N8A+95KPgo0eRJsA7JpSqikuct66SB0K4/sRPsojRpXD
xTcBZd3AnBz5HiNIamjz2MRNl3j+lmtJHnoJ8tgFlitgrr+tWB1c+F4MUzwV+wf9
fQpTeMMyOQqDXPY5MdDyFxKOYli5AgMBAAECgYBcDsg35c/bM8GlL0eUmZwdtY7Y
0crTsVU4MfxHvRA8/1uJ5E3H/hhjpNTm45z5xkUbDsJUsckKbRN0wFoaWDF4L8ZP
AysImKDFSBrFu8ObG5KmpiqSOhmGChkC5Ry3xFplQ3zM10SxcKpGFtTrVTYTLnzt
HI9Du9quD2GQ+JxUcQJBANG+Q+qCN5jiiiB4Hwq5dN731E6PdVHicr6WdZehejc1
Mzw4Qht0op+XV7cRBXoz2si7ICziDDLqqGzsyPcCaQUCQQC+vG+isMUTeDVyPaRZ
ZZlzYFLtQx/7HGc+G0FHfHdP8PJMSeQRe8Yt1EG5QZYqHFSlFwGRwF8Bp0mOFhSp
gG8lAkBIpgqIM8pmHjGRxYmbAVnF0TmsbGxKjJEKCrt4ZeobLUYt2Z6sO94IQTeU
pUSsa0GgvZALe9CV4kmsUOfbBu6xAkEAsIoTPd8lmd6ygVnCq6fZPywRtV9i03a3
rIlng3YVrN1UNv5RZUlN5g9HAeRNzA5K3j8MCc6nYQ1ojGWtnDGvLQJBAK0M6m5F
2fU5p6NxJXJYl+e17+AF8heshTtZB+Cx8JHPIzeXQfV2BHQSIJuN8hxSM57znXNi
/TZJdpx2xQngCpo=
-----END RSA PRIVATE KEY-----

Categories