Convert RSA private key to bytes array - docusignapi

I need to pass a private_key_bytes: the byte contents of the RSA private key in api_client.request_jwt_user_token() API. How do I convert RSA private key to byte array?

I'm assuming you're using Python and using our SDK.
Here is a code snippet taken out of our code examples on GitHub:
(this line does it - private_key = cls._get_private_key().encode("ascii").decode("utf-8")
def _jwt_auth(cls):
"""JSON Web Token authorization"""
api_client = ApiClient()
api_client.set_base_path(DS_JWT["authorization_server"])
# Catch IO error
try:
private_key = cls._get_private_key().encode("ascii").decode("utf-8")
except (OSError, IOError) as err:
return render_template(
"error.html",
err=err
)
try:
cls.ds_app = api_client.request_jwt_user_token(
client_id=DS_JWT["ds_client_id"],
user_id=DS_JWT["ds_impersonated_user_id"],
oauth_host_name=DS_JWT["authorization_server"],
private_key_bytes=private_key,
expires_in=3600
)

Related

Python 3 write encrypted string of bytes to file

I encrypt string:
def encrypt(self, message):
obj = AES.new('This is a key123'.encode("utf8"), AES.MODE_CFB, 'This is an IV456'.encode("utf8"))
encrypted = obj.encrypt(message.encode("utf8"))
return encrypted
How can I store encrypted in a file and read to decrypt using:
def decrypt(self, encrypted):
obj = AES.new('This is a key123'.encode("utf8"), AES.MODE_CFB, 'This is an IV456'.encode("utf8"))
decrypted=obj.decrypt(encrypted)
return decrypted
THe library "pycryptodome" has a full running example for AES encryption to a file and vice versa.
I know that the example runs another mode and stores additional data but that might be helpfull to you as the usage of a static IV is UNSECURE: https://pycryptodome.readthedocs.io/en/latest/src/examples.html
The following code generates a new AES128 key and encrypts a piece of data into a file. We use the EAX mode because it allows the receiver to detect any unauthorized modification (similarly, we could have used other authenticated encryption modes like GCM, CCM or SIV).
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
key = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(data)
file_out = open("encrypted.bin", "wb")
[ file_out.write(x) for x in (cipher.nonce, tag, ciphertext) ]
file_out.close()
At the other end, the receiver can securely load the piece of data back (if they know the key!). Note that the code generates a ValueError exception when tampering is detected.
from Crypto.Cipher import AES
file_in = open("encrypted.bin", "rb")
nonce, tag, ciphertext = [ file_in.read(x) for x in (16, 16, -1) ]
# let's assume that the key is somehow available again
cipher = AES.new(key, AES.MODE_EAX, nonce)
data = cipher.decrypt_and_verify(ciphertext, tag)

Encrypting strings with a predetermined key

I'm trying to make a program that fetches someone's MAC Address from their machine, encrypts it, and then copies it to their clipboard. However, all of the encryption methods I see generate a fresh key and thus can't be deciphered without knowing the specific key that was used to encrypt the address. Is there a way to use one key to encrypt everything so all addresses can be decrypted with a single key, and a fresh key is not generated every single time?
you can try it, using Fernet Lib:
from cryptography.fernet import Fernet
# IMPORTANT: The encryption key must be binary, so the prefix 'b' before the string
# To create a random binary key, use 'generate_key' method as below:
# new_key = Fernet.generate_key()
crypto_key = b'dTlQeWw2u5oMoFPHXQ7vQHPaQUEiD71SYzWeJJAQQUk='
mac = '00:33:A4:D9:F1:E1'
fernet = Fernet(crypto_key)
enc_mac = fernet.encrypt(mac.encode())
dec_mac = fernet.decrypt(enc_mac).decode()
print(f'Fixed encryption key: {crypto_key}')
print('Original MAC string: ', mac)
print('Encrypted MAC string: ', enc_mac)
print('Decrypted MAC string: ', dec_mac)
You are describing asymmetric encryption here.
That exists and is a thing, yes. It works by by having a public key for encryption, and a private key for decryption.
There are multiple algorithms that implement that, like RSA.
RSA is supported by the python library cryptography.
A tutorial on how to use it can be found for example here:
https://nitratine.net/blog/post/asymmetric-encryption-and-decryption-in-python/
Working example
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
# Generate keys. This only has to be done once.
# Store the keys somewhere and distribute them with the program.
def generate_keys():
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
private_key_string = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()
)
public_key_string = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
return (public_key_string, private_key_string)
# This is just for demonstration.
# In practice, don't generate them every time.
# Only generate them once and store them in a string or a file.
(public_key_string, private_key_string) = generate_keys()
# REMOTE COMPUTER
# Only use the public key here, the private key has to stay private.
public_key = serialization.load_pem_public_key(public_key_string, backend=default_backend())
mac_address = "01:23:45:67:89:AB"
mac_address_encrypted = public_key.encrypt(
mac_address.encode(),
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# LOCAL SERVER
# Use private keys here to decrypt the MAC address
private_key = serialization.load_pem_private_key(private_key_string, password=None, backend=default_backend())
mac_address_decrypted = private_key.decrypt(
mac_address_encrypted,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
).decode()
print(mac_address_decrypted)
https://ideone.com/0eEyU6
You can use Import RSA library rsa
installing :
pip install rsa
Then encrypt the byte string with the public key.
Then the encrypted string can be decrypted with the private key.
The public key can only be used for encryption and the private can only be used for decryption
for examle:
import rsa
publicKey, privateKey = rsa.newkeys(512)
message = "Salio" #this is MAC Address
encMessage = rsa.encrypt(message.encode(), publicKey)
print("encrypted: ", encMessage)
decMessage = rsa.decrypt(encMessage, privateKey).decode()
print("decrypted : ", decMessage)

Decrypt data using cryptography package giving error "ValueError: Encryption/decryption failed."

import base64
import os.path
from shutil import copyfile
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding, rsa
from cryptography.hazmat.backends.openssl.rsa import _RSAPublicKey, _RSAPrivateKey
from asym_crypto_yaml import (decrypt_value, encrypt_value, Encrypted,
load_private_key_from_file, load_public_key_from_file,
generate_new_private_key, generate_new_public_key,
load, dump, NUMBER_OF_BYTES_PER_ENCRYPTED_CHUNK, KEY_CHUNK_SIZE,
SUPPORTED_KEY_SIZES, generate_private_key_to_file, generate_private_key_to_file, generate_public_key_to_file,
encrypt_value_and_print ,add_secret_to_yaml_file, decrypt_yaml_file_and_write_encrypted_file_to_disk,
reencrypt_secrets_and_write_to_yaml_file)
from functools import reduce
def test_add_secret_to_yaml_file():
private_key_output_filename = "/home/asy/private_key.private"
public_key_output_filename = "/home/asy/public_key.public"
private_key = generate_private_key_to_file(private_key_output_filename)
public_key = generate_public_key_to_file(private_key_output_filename, public_key_output_filename)
yaml_file_fixture = "/home/asy/saml.yml"
yaml_file_to_append_to = "/home/asy/saml_du.yml"
test_key_to_encrypt = ['FACEBOOK_APP_ID', 'FACEBOOK_APP_SECRET', 'AWS_S3_BUCKET', 'SECRET_TOKEN', 'TWITTER_CONSUMER_KEY', 'TWITTER_CONSUMER_SECRET',
'TWITTER_OAUTH_TOKEN', 'TWITTER_OAUTH_TOKEN_SECRET', 'LINKEDIN_API_KEY', 'LINKEDIN_SECRET_KEY']
print ("################################ENCRYPT YAML########################################")
before_dict = None
with open(yaml_file_to_append_to, "r") as f:
before_dict = load(f)
# Encrypt data in yml file
for test_key in test_key_to_encrypt:
print ('Encrypted key is:', test_key)
print ('Encrypted value is:', before_dict[test_key])
add_secret_to_yaml_file(test_key, before_dict[test_key], public_key_output_filename, yaml_file_to_append_to)
print ("################################DECRYPT YAML########################################")
before_dict = None
with open(yaml_file_to_append_to, "r") as f:
before_dict = load(f)
# Decrypt data from yml file (Using same function)
for test_key_value in test_key_to_encrypt:
print ('key is', before_dict[test_key_value])
test_encrypted_key_value = decrypt_value(before_dict[test_key_value], private_key)
print ("decrypt data", test_encrypted_key_value)
#
def decrypt_data():
private_key_output_filename = "/home/asy/private_key.private"
public_key_output_filename = "/home/asy/public_key.public"
private_key = generate_private_key_to_file(private_key_output_filename)
public_key = generate_public_key_to_file(private_key_output_filename, public_key_output_filename)
yaml_file_to_append_to = "/home/asy/saml_du.yml"
test_key_to_encrypt = ['FACEBOOK_APP_ID', 'FACEBOOK_APP_SECRET', 'AWS_S3_BUCKET', 'SECRET_TOKEN', 'TWITTER_CONSUMER_KEY', 'TWITTER_CONSUMER_SECRET',
'TWITTER_OAUTH_TOKEN', 'TWITTER_OAUTH_TOKEN_SECRET', 'LINKEDIN_API_KEY', 'LINKEDIN_SECRET_KEY']
print ("################################DECRYPT YAML########################################")
before_dict = None
with open(yaml_file_to_append_to, "r") as f:
before_dict = load(f)
for test_key_value in test_key_to_encrypt:
print ('key is', test_key_value)
print ('value is', before_dict[test_key_value])
test_encrypted_key_value = decrypt_value(before_dict[test_key_value], private_key)
print ("decrypt data", test_encrypted_key_value)
if __name__ == "__main__":
test_add_secret_to_yaml_file()
# decrypt_data()
sample yml file:
SECRET_TOKEN: "d4e5783de1c74c7a4e3a27578df6gdgf6g786g8df7g6g87d6fgb709"
FACEBOOK_APP_ID: "35864341"
FACEBOOK_APP_SECRET: "759a1e7sd7fvyfsd473"
TWITTER_CONSUMER_KEY: "1UrRKJDF8SD7FSDF3S"
TWITTER_CONSUMER_SECRET: "5W7TE8KJJk787bnG0s"
TWITTER_OAUTH_TOKEN: "716397744-3rHXFkFkjKjkjK78PQ5"
TWITTER_OAUTH_TOKEN_SECRET: "DuDJKFSD89SDFD"
LINKEDIN_API_KEY: "2vjkJKjk4"
LINKEDIN_SECRET_KEY: "5KLSJDFsE"
GMAIL_USERNAME: "username#gmail.com"
GMAIL_PASSWORD: "PASSWORD"
AWS_ACCESS_KEY_ID: "ASDKLSDJFIA"
AWS_SECRET_ACCESS_KEY: "7ASDFJksdfjskdlf87sdfKb"
AWS_S3_BUCKET: "bucket"
development:
MAILER_HOST: "localhost:3000"
test:
MAILER_HOST: "localhost:3000"
production:
MAILER_HOST: "domain.com"
I am using "asym_crypto_yaml" yaml package to write encrypted value in .yml file.
I am not able to decrypt value from different decrypt function (decrypt_data()).
Above code only decrypt value if I execute code first time. But from second time its giving "encryption/decryption error".
My objective is to decrypt data from yml file. Little help will be appreciated.
The error is triggered because the private key used in decrypt_data() for decryption does not belong to the public key used in test_add_secret_to_yaml_file() to perform the encryption. Therefore, decryption with this private key fails.
The problem can be solved by using in decrypt_data() the private key of the key pair generated in test_add_secret_to_yaml_file(). To do this, remove the generate_private_key_to_file() and generate_public_key_to_file() calls (to generate and store a key pair) in decrypt_data(). The required private key can be loaded with load_private_key_from_file() from the file where it was stored in test_add_secret_to_yaml_file().
This ValueError: Encryption/decryption failed. Error is also thrown by the hazmat class when the data you want to encrypt is too large for the size of key that you generated. Try again by using larger key size like this.
private_key = rsa.generate_private_key(public_exponent=65537, key_size = 4096)
but keep in mind it will increase time to generate key, that is one of the biggest disadvantage of RSA encryption algorithm.

this decryption code use already-given encrypted private key to decrypt the AES (session) key. an error occurred

code looks something like this:
from Crypto.Cipher import AES
import os
import base64
def decryption(encryptedString):
PADDING ='{'
DecodeAES=lambda c, e:c.decrypt(base64.b64decode(e)).rstrip(PADDING)
a = open('private_key0.pem','rb')
key = a.read()
print(key)
cipher = AES.new(key)
decoded = DecodeAES(cipher,encryptedString)
print (decoded)
a.close()
s = open('session_key0.eaes','rb')
cipher_text = s.read()
print(cipher_text)
s.close()
decryption(cipher_text)
error is in line cipher = AES.new(key) and decryption(cipher_text) saying missing mode.Do i need to encrypt the already excrypted files or what?

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