1
votes

Hi Google Cloud KMS team, are there any Google Cloud KMS plaintext size limitations to encrypt by key types for asymmetric and symmetric keys ?

Because we would like to encrypt/decrypt REST flow between frontend(browser) and backend(REST microservices) and would like to use Asymmetric approach (not Hybrid):

  1. generate Frontend key-pair Data encrytion Public/Private keys (using javascript libs) - Data encrytion Public key is not encrypted by KEK

  2. generate Backend key-pair Data encrytion Public/Private keys (using barricade with Google KMS) - Data encrytion Public key is not encrypted by KEK

  3. exchange Data encrytion Public keys between Frontend and Backend to be able to encypte requests from Frontend to Backend and responses from Backend to Frontend back

We would like to store frontend generated asymmetric public/private keys during some calls session(in browser) and backend asymmetric public/private keys will be generated by google KMS

So, are there any Google Cloud KMS plaintext size limitations to encrypt by key types for asymmetric key?

1
I would use a hybric/envelope approach for this, where you generate a random symmetric key (the DEK) and then wrap that DEK with an asymmetric algorithm for transport. Can you clarify why you do not want to do this? - Tim Dierks
Hi @Tim, yes we were looking in to hybrid approach, but don't want to send private key (even encrypted with public key) between frontend and backend, we would like to use more secured approach - asymmetric - to send public keys only - Iurii Smyrnov
I don't understand your design constraint or security concern, hybrid solutions combining symmetric and asymmetric algorithms to get the benefit of each are common and broadly used. I disagree that just using asymmetric is "more secured" in any interesting way. - Tim Dierks

1 Answers

3
votes

In addition to a discussion of what the best protocol design for you is, to answer the specific question: the maximum payload size for RSA decryption is dependent on the key size and padding algorithm. All currently supported RSA encryption formats use OAEP, standardized in RFC 2437. You will see there that the message is:

an octet string of length at most k-2-2hLen, where k is the length in octets of the modulus n and hLen is the length in octets of the hash function output for EME-OAEP

So this leads to the following max lengths for m:

RSA_DECRYPT_OAEP_2048_SHA256: k = 256; hLen = 32; maxMLen = 190
RSA_DECRYPT_OAEP_3072_SHA256: k = 384; hLen = 32; maxMLen = 318
RSA_DECRYPT_OAEP_4096_SHA256: k = 512; hLen = 32; maxMLen = 446
RSA_DECRYPT_OAEP_4096_SHA512: k = 512; hLen = 64; maxMLen = 382

If you try to encrypt a message larger than this limit, your client-side will fail as unable to encrypt, so there's no question as to what KMS will do with a message too long.

Here's my test to verify that Cloud KMS can decrypt a message to the full length for a 2048bit RSA key:

# create an rsa2048-256 encryption key

tdierks@cloudshell:~ (kms-test-1367)$ gcloud kms keyrings create --location global so-60686427
tdierks@cloudshell:~ (kms-test-1367)$ gcloud kms keys create rsa-2048-256 --keyring so-60686427 --location global --purpose asymmetric-encryption --default-algorithm rsa-decrypt-oaep-2048-sha256
tdierks@cloudshell:~ (kms-test-1367)$ gcloud kms keys versions list --key rsa-2048-256 --keyring so-60686427 --location global
NAME                                                                                                      STATE
projects/kms-test-1367/locations/global/keyRings/so-60686427/cryptoKeys/rsa-2048-256/cryptoKeyVersions/1  ENABLED

# get the public key

tdierks@cloudshell:~ (kms-test-1367)$ gcloud kms keys versions get-public-key 1 --key rsa-2048-256 --keyring so-60686427 --location global > /tmp/rsa-2048-256.pub
tdierks@cloudshell:~ (kms-test-1367)$ cat /tmp/rsa-2048-256.pub
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyvN5iBbV7daXKocL0CuB
bM+gaPMEigS6N8Jl9g7AY7ocrvNDONBa5JZzJTuMkNqgq21PZ1CUBD76jJlUOBgY
Nmj+sMNKw1c+slx47fvyK2uVMcmEEAfCcnUt2fK86v7v8UddbH/BNK+SobarkOQC
1kM74qdhKSvFFz+F9kAzrby4VjCxfWsDYCeFhS9Jrkxl6l/Z2WANy34y9ztbgJdi
eSugA7b/VfrlsxYz7xu498UWDbVbOPKs7UGB14icK4SVoF0irk7dWxNvAQD21mJU
YPAFmJ/MTQ+v3l+uEOrdicb9FcM6WNmyTwkN6DYcuD7eJYVwwz1sU8Y631swbjlS
wQIDAQAB
-----END PUBLIC KEY-----

# test it by encrypting a test message and decrypting it

tdierks@cloudshell:~ (kms-test-1367)$ echo "squeamish ossifrage" | openssl pkeyutl -encrypt -pubin -inkey /tmp/rsa-2048-256.pub -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256 > /tmp/rsa-2048-256.enc
tdierks@cloudshell:~ (kms-test-1367)$ gcloud kms asymmetric-decrypt --location global --keyring so-60686427 --key rsa-2048-256 --version 1 --ciphertext-file /tmp/rsa-2048-256.enc --plaintext-file /dev/stdout
squeamish ossifrage

# generate a 190 byte message, encrypt it, and decrypt it, verify by comparing md5sum

tdierks@cloudshell:~ (kms-test-1367)$ dd ibs=190 count=1 < /dev/urandom > /tmp/message-190
1+0 records in
0+1 records out
190 bytes copied, 0.0002066 s, 920 kB/s
tdierks@cloudshell:~ (kms-test-1367)$ ls -l /tmp/message-190
-rw-r--r-- 1 tdierks tdierks 190 Mar 15 14:54 /tmp/message-190
tdierks@cloudshell:~ (kms-test-1367)$ openssl pkeyutl -in /tmp/message-190 -encrypt -pubin -inkey /tmp/rsa-2048-256.pub -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256 > /tmp/rsa-2048-256-m190.enc
tdierks@cloudshell:~ (kms-test-1367)$ gcloud kms asymmetric-decrypt --location global --keyring so-60686427 --key rsa-2048-256 --version 1 --ciphertext-file /tmp/rsa-2048-256-m190.enc --plaintext-file /dev/stdout | md5sum
4932e23fb11c094c1dd703ba34afc565  -
tdierks@cloudshell:~ (kms-test-1367)$ md5sum /tmp/message-190
4932e23fb11c094c1dd703ba34afc565  /tmp/message-190

# try again with 191 bytes

tdierks@cloudshell:~ (kms-test-1367)$ dd ibs=191 count=1 < /dev/urandom > /tmp/message-191
1+0 records in
0+1 records out
191 bytes copied, 7.2545e-05 s, 2.6 MB/s
tdierks@cloudshell:~ (kms-test-1367)$ ls -l /tmp/message-191
-rw-r--r-- 1 tdierks tdierks 191 Mar 15 14:59 /tmp/message-191
tdierks@cloudshell:~ (kms-test-1367)$ openssl pkeyutl -in /tmp/message-191 -encrypt -pubin -inkey /tmp/rsa-2048-256.pub -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256 > /tmp/rsa-2048-256-m191.enc
Public Key operation error
140191432818944:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=/home/tdierks/.rnd
140191432818944:error:0409A06E:rsa routines:RSA_padding_add_PKCS1_OAEP_mgf1:data too large for key size:../crypto/rsa/rsa_oaep.c:62:

As you can see, OpenSSL failed on encrypting a 191 byte input file.