Fork me on GitHub
#crypto
<
2021-06-14
unbalanced14:06:58

Hi there! I'm struggling with what are probably some basic crypto questions. I'm trying to port some code from Python to Clojure.

(def some-key-bytes-in-base64 (make-random-bytes->b64 256))
(def public-key-text "-----BEGIN PUBLIC KEY-----QfAt0/EME\n...snip...AwIDAQAB\n-----END PUBLIC KEY-----\n")
(def rsa (rsa-fn??? public-key-text))
(def encrypted-key (rsa-encrypt??? rsa some-key-bytes-in-base64))
(def secret-message "hi")
(def aes-encrypted-secret-message (aes-encrypt??? (b64->bytes some-key-bytes-in-base64) secret-message))
(def response (send-secret-message-and-encrypted-key aes-encrypted-secret-message encrypted-key))
(def decrypted-results (aes-decrypt??? (b64->bytes some-key-bytes-in-base64) response))
Some further details -- the RSA is using PKCS1 v1.5, and the AES is using PKCS7

unbalanced14:06:22

Here is the corresponding Python code:

import base64
import os
from pkcs7 import PKCS7Encoder
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5


class AESManager(object):

    def __init__(self, key=None, iv=None):
        self.key = key if key else base64.b64encode(os.urandom(16))
        self.iv = iv if iv else '\x00' * 16
        self.encoder = PKCS7Encoder()

    def encrypt(self, data):
        aes = AES.new(self.key, AES.MODE_CBC, self.iv)
        padded_text = self.encoder.encode(data)
        cipher_text = aes.encrypt(padded_text)
        return base64.b64encode(cipher_text)

    def decrypt(self, data):
        aes = AES.new(self.key, AES.MODE_CBC, self.iv)
        cipher_text = base64.b64decode(data)
        clear = aes.decrypt(cipher_text)
        text = self.encoder.decode(clear.decode('utf-8'))
        return text


class RSAManager(object):

    def __init__(self, public_key=None, private_key=None):
        self.public_key = RSA.importKey(public_key) if public_key else None
        self.private_key = RSA.importKey(private_key) if private_key else None

    def encrypt(self, data, encode=True):
        if not self.public_key:
            raise Exception("Cannot encrypt without public key")
        cipher = PKCS1_v1_5.new(self.public_key)
        encrypted_data = cipher.encrypt(data)
        encrypted_data = base64.b64encode(encrypted_data) if encode else encrypted_data
        return encrypted_data

    def decrypt(self, data, decode=True):
        if not self.private_key:
            raise Exception("Cannot decrypt without private key")
        data = base64.b64decode(data) if decode else data
        cipher = PKCS1_v1_5.new(self.private_key)
        return cipher.decrypt(data, None)