Radix 64 and encryption - python

Need to share my problem that is :
A PGP public key server gives me the key in Radix64 format .
And i searching for any method which can encrypt my message using this Radix64 format public key .
any alternate suggestions or documents are welcome .........

exPyCrypto looks good.
This previous SO question addresses Radix64 format specifically for public keys.
To convert the actual base/radix64 encoded characters, see this question:
import base64
decoded_bytes = base64.b64decode(ascii_chars)

You can decode the key by using the base64 module and then encrypt the message.

Related

Encryption with NodeJS doesn't match encryption using Python (cryptography.fernet)

Cryptography noob here. I'm trying to write a script in NodeJS that encrypts a string and produces output that matches the output of my Python script that uses the cryptography.fernet library. My overall goal is to use the original key to encrypt messages in Node that will later be decrypted using Python.
Sample of my Python code:
from cryptography.fernet import Fernet
key = Fernet.generate_key() # For example: 6saGtiTFEXej729GUWSeAyQdIpRFdGhfY2XFUDpvsu8=
f = Fernet(key)
message = 'Hello World'
encoded = message.encode()
encrypted = f.encrypt(encoded)
Which produces the output: gAAAAABhJs_E-dDVp_UrLK6PWLpukDAM0OT5M6bfcqvVoCvg7r63NSi4OWOamLpABuYQG-5wsts_9h7cLbCsWmctArXcGqelXz_BXl_o2C7KM9o7_eq7VTc=
My Node script uses the built-in Crypto module and must also use the same 32-byte key that is being used in my Python program. I know that fernet uses is AES-128-CBC as its algorithm, so that's what I'm using for my Node script.
My NodeJS code:
const crypto = require("crypto");
const key = '6saGtiTFEXej729GUWSeAyQdIpRFdGhfY2XFUDpvsu8=';
const algorithm = 'aes-128-cbc';
const message = 'Hello World';
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
const encrypted = cipher.update(message, 'utf8', 'hex') + cipher.final('hex');
Which is giving me: Error: Invalid key length
My first problem is that I'm unsure how to convert the key so that it's the proper length. I also know from looking at fernet's source code that the key is split into two parts: the first 16 bytes are the signing_key and the last 16 bytes are the encryption_key - I haven't found much information on whether/how I need to deal with those two pieces of the original key in my Node implementation.
Since I'm new to this I'm a little confused on how to accomplish what I'm after. Any tips or advice is very much appreciated.
The specs for the Fernet format can be found on https://github.com/fernet/spec/blob/master/Spec.md
There they specify both a generating and a veryfying steps, here is the generating which should give enough information for your implementation:
Record the current time for the timestamp field.
Choose a unique IV.
Construct the ciphertext:
Pad the message to a multiple of 16 bytes (128 bits) per RFC 5652, section 6.3. This is the same padding technique used in PKCS #7 v1.5 and all versions of SSL/TLS (cf. RFC 5246, section 6.2.3.2 for TLS 1.2).
Encrypt the padded message using AES 128 in CBC mode with the chosen IV and user-supplied encryption-key.
Compute the HMAC field as described above using the user-supplied signing-key.
Concatenate all fields together in the format above.
base64url encode the entire token.
From this we can see that the signing key (first half of full key) is used in HMAC, while the second half is used in the AES128-CBC, so just dividing the key into two separate elements (with proper conversion from hex string to bytes) should be enough for using Node.js crypto module (https://nodejs.org/en/knowledge/cryptography/how-to-use-crypto-module/) to construct your own implementation.

Encryption not working properly

i have this piece of code for encryption.
from cryptography.fernet import Fernet
key = Fernet.generate_key()
f = Fernet(key)
token = f.encrypt(b"something cool")
k = f.decrypt(token)
print(k) `
This is the output
b'something cool'
According to the example on the website, that "b" should've gone. I'm very new at this and would like to know or understand how exactly the solution works.
Thanks
That ‘b’ means bytes. So instead of working with strings encryption algorythms are actually using bytes. My experience is that what you give a library (str/bytes/array) it should give you back, which Fernet is doing. I would simply convert the bytes back to a string k.decode(“utf-8”)
The encryption functions are doing what they should: bytes in and bytes out.
Cryptography and encryption work with bytes, not strings or other encoding, decrypt returns bytes. The actual low level decrypt has no idea of encodings, it can't the decryption could be a string, it could be an image, etc.
It is up to the caller to provide encodings in and out that are appropriate to the data being encrypted/decrypted.
As the caller wrap the encryption in a function you write that provides the correct encodings, in this case a string to bytes on encryption and bytes back to a string on decryption.

Using a byte array as key for AES algorithm in Python

I have a byte array that is a 128 bits AES key and I want to use that one on a Python script to cipher some information using the aforementioned key.
I have the key stored as a hexadecimal string, something like "27821D90D240EA4F56D0E7612396C69E" (obviously this is not the real key, but has the same format).
I have generated a byte array from that key, that is the way I have been using AES keys in other languages (Java, C# and PHP) so far, like this:
AES_KEY = bytearray.fromhex('27821D90D240EA4F56D0E7612396C69E')
That works fine, but then when I try to use it for creating the cipher, it complains that it wants an string in the first parameter:
cipher = AES.new(AES_KEY, AES.MODE_CBC, os.urandom(16));
TypeError: argument 1 must be string or read-only buffer, not
bytearray
I have tried to get an string from the byte array instead, as:
AES_KEY = bytearray.fromhex('27821D90D240EA4F56D0E7612396C69E').decode()
or
AES_KEY = bytearray.fromhex('27821D90D240EA4F56D0E7612396C69E').decode('utf-8')
to no avail because there are non-ascii and non-unicode values in that key.
Replacing the key is NOT an option.
Any ideas?
Thanks a lot in advance,
Apparently this does the trick:
AES_KEY = str(bytearray.fromhex('27821D90D240EA4F56D0E7612396C69E'))
It looks pretty obvious now, doesn't it?

Python RSA encrypted message pass to other languages to decypt

I am using the RSA python package to encrypt a message and try to pass it to a PHP site to decrypt. See below:
message = rsa.encrypt('abc', pubkey)
print message
print type(message)
What I get is some encrypted text
q??$$??kK?Y??p?[e?[??f???x??s!?s?>?z?*y?p?????????分?
? ???({u????NH?B???N?%?#5|?~?????\U?.??r?Y?q
<type 'str'>
What's the best way to pass it to other languages to decrypt?
That's not a text, it's a binary data. As you are using python2 it doesn't fully distinguish bytes from str so you should care about this.
The other side should get this bytes exactly as rsa outputs them so you can just write them into your connection or file (presuming you are talking binary to them).
For web you can base64 encode the data. It's a common and good way to encode binary data.
>>> import base64
>>> base64.b64encode(b"data")
'ZGF0YQ=='
>>> base64.b64decode(base64.b64encode(b"data"))
'data'
By the way you are not suppose to use RSA that way. It's highly insecure to use raw RSA. You must use a probabilistic encryption scheme with proper padding, e.g. RSAES-OAEP. PKCS#1 defines such scheme for encryption and signatures.

ECC key encoding in pyecc and seccure

I am working with pyecc which uses the seccure C library.
When a public key is generated I get something back like this:
#Gp}7RRWK5Dyg&-m5yHve1p{?<o0xi.M8-?W^]xb))oA]|qO%[5v?#IxteV?
Are these the 'raw bytes' or is this encoded in some form? When I use os.urandom(16) I get all kinds of messed up characters, but not from this generate public key function. Does that mean that there is some encoding? I've looked at the seccure source code, but I still don't understand why I get all these 'normal' characters.
How do I turn this into a byte array (Python bytearray) of the exact key?
Code:
from pyecc import ECC
ecc = ECC.generate()
print ecc._public
It looks like it might be a proprietary format from quickly looking at their code. They serialize and compress the key information into a printable string. You can download the source code and see an example of how to use it here: http://point-at-infinity.org/seccure/.

Categories