RSA encryption scheme
SDK functions for RSA key generation, encryption, and decryption, used to obtain the user AES key.
Bubble utilizes the RSA encryption scheme to acquire the user AES key necessary for encrypting and decrypting data.
The SDK provides several RSA functionalities to support this.
Below are the function signatures for these functionalities, provided in Python and JavaScript:
- Generate RSA key pair
def generate_rsa_keypair()- Encrypt
def encrypt_rsa(public_key_bytes, plaintext)- Decrypt
def decrypt_rsa(private_key_bytes, ciphertext)Example usage - Onboard user
Bubble employs AES keys unique to each user for the encryption and decryption of their values.
To retrieve the AES key, the user must request the User Interactor to return the key associated with the sending user.
Further details regarding this process are outlined in the onboard user section:
The OnboardUser function in the User interactor takes a signed RSA public key as a parameter. It then verifies the signature to ensure the authenticity of the RSA public key. Once the signature is verified, the function proceeds to encrypt the AES key using the verified RSA public key.
For a comprehensive understanding of the sign process, please refer to the detailed explanation provided at:
We offer a script that accomplishes the following tasks using Bubble SDK:
- Generates an RSA key pair.
- Signs the public key.
- Invokes the
OnboardUserrpc request to the User Interactor, passing the signed public key. - Accepts the encrypted AES key shares.
- Decrypts the AES key shares using the private RSA key and reconstructs the AES key.
Below are examples of such script implemented in Python:
def onboard_user(client, signing_private_key):
# Create RSA key pair
rsa_private_key, rsa_public_key = generate_rsa_keypair()
# Get the Ethereum address from private key
account = Account.from_key(signing_private_key)
user_address = to_bytes(hexstr=account.address)
message = rsa_public_key + user_address
# Sign the rsa public key
signature = sign_eip191(message, bytes.fromhex(signing_private_key[2:]))
# Call the gRPC service
request = pb.OnboardUserRequest(
rsa_public_key=rsa_public_key,
address=user_address,
user_signature=signature
)
response = client.OnboardUser(request)
# Split the response into two ciphers
cipher0 = response.rsa_ciphertexts[:RSA_CIPHERTEXT_SIZE]
cipher1 = response.rsa_ciphertexts[RSA_CIPHERTEXT_SIZE:]
# Decrypt the ciphers
share0 = decrypt_rsa(rsa_private_key, cipher0)
share1 = decrypt_rsa(rsa_private_key, cipher1)
# XOR the key shares to get the user AES key
user_aes_key = bytes(a ^ b for a, b in zip(share0, share1))
return user_aes_key