lua-openssl icon indicating copy to clipboard operation
lua-openssl copied to clipboard

Question about RSA-OAEP-256 use/support

Open r-oueslati opened this issue 3 years ago • 11 comments

Hello,

  • uname -a or OS info: Linux 1edcdde59df8 5.10.25-linuxkit #1 SMP Tue Mar 23 09:27:39 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux (Ubuntu 18.04)
  • openssl version or OPENSSL_VERSION_TEXT in your opensslv.h: OpenSSL 1.1.1 11 Sep 2018
  • lua -v or luajit -v: LuaJIT 2.1.0-beta3
  • lua -e "print(require'openssl'.version())" or luajit -e "print(require'openssl'.version())": 269488207`

Problem details I can't really say it is a problem and I don't think it is a bug. I already successfully used lua-openssl to implement JWS signature verification. Now I'm trying to implement some basic JWE decrypting feature in a Kong plugin. To do so, I need to decrypt the JWE Encrypted Key using RSA-OAEP-256 (RSAES OAEP using SHA-256 and MGF1 with SHA-256) and then I need to decrypt the JWE Cipher Text using A256GCM (AES GCM using 256-bit key).

I'm stuck at the first step. I tried to use the evp_pkey class like this: local encryptionkey = pkey:decrypt(encryptedkey,'oaep'). And I get this error: rsa_pk1.c:251:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error

I managed to do it using openssl command line: openssl pkeyutl -in encrypted_key.bin -out encryption_key.bin -inkey rsa_private_key.pem -decrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256

My question is: am I doing anything wrong or is it just not supported by the library ?

Steps/codes to reproduce the bug

  1. local key = "-----BEGIN RSA PRIVATE KEY----- [..]"
  2. local pkey_ok, pkey = pcall(openssl_pkey.new, key)
  3. local encryptionkey = pkey:decrypt(encryptedkey,'oaep')

Expected result

Additional context I'm using Kong 1.5 which includes lua-openssl.

Thank you for your help. Ramzi

r-oueslati avatar Jul 31 '21 06:07 r-oueslati

This is add binding to https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/doc/man3/RSA_padding_add_PKCS1_type_1.pod, please wait sometimes.

zhaozg avatar Aug 01 '21 03:08 zhaozg

to @r-oueslati, please look at https://github.com/zhaozg/lua-openssl/commit/065ac62ad8eee766e3d066e705d65c440373b404 https://github.com/zhaozg/lua-openssl/commit/065ac62ad8eee766e3d066e705d65c440373b404#diff-979504a39f6acd5651c1289f2c30998f28a689ea9eebec27e55103ead5ded530R90-R106 show you howto do openssl pkeyutl -in encrypted_key.bin -out encryption_key.bin -inkey rsa_private_key.pem -decrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 in lua mode.

zhaozg avatar Aug 01 '21 05:08 zhaozg

Thank you @zhaozg for your quick reply. I will try that and let you know.

r-oueslati avatar Aug 01 '21 08:08 r-oueslati

When I will manage to decrypt the JWE encrypted key I will have to use this decrypted key to decrypt the cipher text. I will do so using the iv and the authentication tag provided in the JWE. I didn't see any reference to the authentication tag in the cipher class so I'm guessing AES-256-GCM symmetric encryption/decryption is not yet supported. Could it be a new feature request as well ?

Thank you

r-oueslati avatar Aug 01 '21 08:08 r-oueslati

I'm guessing AES-256-GCM symmetric encryption/decryption is not yet supported.

Yes, that's need to do, and need more time.

zhaozg avatar Aug 01 '21 09:08 zhaozg

@r-oueslati Please look at https://github.com/zhaozg/lua-openssl/blob/master/test/issue%23156.lua and https://github.com/zhaozg/lua-openssl/issues/156 Maybe that will make you happy, and I not use AES-256-GCM, so ...

zhaozg avatar Aug 01 '21 09:08 zhaozg

Thank you so much @zhaozg. In the meantime I managed to do the AES-256-GCM decryption using lua-resty-openssl. But I will definitely look into the example you gave and let you know. Again, thank you for your quick replies :)

r-oueslati avatar Aug 01 '21 10:08 r-oueslati

@r-oueslati Please look at https://github.com/zhaozg/lua-openssl/blob/master/test/issue%23156.lua and #156 Maybe that will make you happy, and I not use AES-256-GCM, so ...

Hello @zhaozg , It did make me happy as I managed to do AES-256-GCM decryption.

local cipher = openssl.cipher.get('aes-256-gcm')
local cipher_ctx = cipher:decrypt_new()
cipher_ctx:init(encryption_key,initvector)
cipher_ctx:update(authtag,true)
cipher_ctx:padding(false)
local payload = cipher_ctx:update(ciphertext)
print(payload)

This works fine :) Now I will look into rsa-oaep-256 decryption.

r-oueslati avatar Aug 05 '21 15:08 r-oueslati

local k = openssl.rsa.read(b64_decode(key2_der))
local padded = k:decrypt(encryptedkey, 'no', true)
local encryption_key = openssl.rsa.padding_check(padded, 'oaep', 256)

But encryption_key is nil. Did I do anything wrong ?

r-oueslati avatar Aug 05 '21 16:08 r-oueslati

local padded,err = k:decrypt(encryptedkey, 'no', true)

if not padded then
  --check decrypt result
  print(err)
  print(openssl.error())  -- get openssl low level error info
end

zhaozg avatar Aug 06 '21 06:08 zhaozg

Hello @zhaozg :)

I picked up where I left off last year and made it work (JWE with alg=RSA-OAEP-256 and enc=A256GCM).

First I parse the JWE to get the encrypted key:

local header_64, encryptedkey_64, initvector_64, ciphertext_64, authtag_64 = unpack(tokenize(jwe, ".", 5))

Then I read decrypt the encryption_key (CEK) using the private key in DER format:

local k = openssl.rsa.read(base64.decode(key_der))
local padded = k:decrypt(encryptedkey, 'no', true)
local encryption_key = openssl.rsa.padding_check(padded, 'oaep', 256, '', 'sha256')

And finally I decrypt the payload:

if (encryption_key) then
  local cipher = openssl.cipher.get('aes-256-gcm')
  local cipher_ctx = cipher:decrypt_new()
  cipher_ctx:init(encryption_key,initvector)
  --cipher_ctx:update(authtag,true)
  cipher_ctx:padding(false)
  local payload = cipher_ctx:update(ciphertext)
  print(payload)
end

I had to comment the authentication tag operation so I guess it is not checked but that will do for now.

Now I'll have a look at alg=ECDH-ES+A256KW.

Thank you again.

r-oueslati avatar Aug 03 '22 18:08 r-oueslati