Решение оказалось не таким простым, как мне показалось на первый взгляд.
Для начала вам нужно понять, что содержимое переменных PrivateKey и PublicKey - это не просто чистый ключ, закодированный в Base64., это объект protobuf, сериализованный в ByteArray, а затем закодированный в Base64.Чтобы получить ключ от него, вам сначала нужно получить схему этого объекта, которая доступна по ссылке .
Мы сохраняем этот файл и следуем инструкциям на эта страница .Короче говоря, я выполнил команду protoc --python_out=. crypto.proto
, чтобы создать модуль Python с именем crypto_pb2.py
.
Все приготовления завершены, и теперь перейдем к коду:
import crypto_pb2
import base64
publicKey = "CAASpgIwgE ... jkupAgMBAAE="
privateKey = "CAASqQkwgg ... Xmzva/Km7A=="
Сначала необходимо декодироватьстрока base64 в байтовом массиве:
decoded = base64.b64decode(publicKey)
Эта функция десериализует массив байтов в знакомый объект protobuf Python, я взял его из этого ответа и немного изменил:
def deserialize(byte_message, proto_type):
module_, class_ = proto_type.rsplit('.', 1)
class_ = getattr(crypto_pb2, class_) # crypto_pb2 is a name of module we recently created and imported
rv = class_()
rv.ParseFromString(byte_message) # use .SerializeToString() to reverse operation
return rv
Далее мы вызываем функцию, передаем декодированный base64 и имя класса, которому он соответствует (PublicKey
для publicKey
и PrivateKey
для privateKey
), меня интересуетсвойство Data
.
publicKey = deserialize(decoded, 'crypto.pb.PublicKey').Data
Теперь вы можете передать его в функцию import_key как ByteArray.Не выполнять дополнительные преобразования.
key = Crypto.PublicKey.RSA.import_key(publicKey)
crypter = Crypto.Cipher.PKCS1_OAEPPKCS1_OAEP.new(key)
encryptedData = crypter.encrypt(data.encode())
result = base64.b64encode(encryptedData).decode()