Soda Labs
Soda Labs Docs
User InterfaceUser SDK

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:

  1. Generates an RSA key pair.
  2. Signs the public key.
  3. Invokes the OnboardUser rpc request to the User Interactor, passing the signed public key.
  4. Accepts the encrypted AES key shares.
  5. 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

On this page