StackNoob
StackNoob

Reputation: 21

PHP RSA encryption openssl issue

I have been racking my brain. I am using the latest version of php 7. I can get rsa working with short text, however long text seems to not work. I read to use openssl_seal/open.. when I demoed the code on a test page it works great.. when I put it into practice with mysql its not working the way its supposed to..

Encryption code:

$messageiv = openssl_random_pseudo_bytes(32);
openssl_seal($_POST[$_SESSION['message']], $encryptedmessage, $ekeys, array($_SESSION['recipient_publickey']), "AES256", $messageiv);
openssl_seal($_POST[$_SESSION['subject']], $encryptedsubject, $ekeys, array($_SESSION['recipient_publickey']), "AES256", $messageiv);

The above is then base91_encoded and stored into blobs/varchar.

To decrypt it

openssl_open(base91_decode($row['messagesubject']), $decryptedsubject, $ekeys[0], $_SESSION['privatersakey'], "AES256", base91_decode($row['messageiv']));              
    openssl_open(base91_decode($row['messagebody']), $decryptedbody, $ekeys[0], $_SESSION['privatersakey'], "AES256", base91_decode($row['messageiv']));

The above variables $decryptedsubject and $decryptedmessage are blank.

I had this issue before using openssl_public/private key encrypt/decrypt and added the padding, this worked, however with long text it won't encrypt/decrypt....

Any assistance would be great...

Upvotes: 2

Views: 512

Answers (1)

Scott Arciszewski
Scott Arciszewski

Reputation: 34113

I can get rsa working with short text, however long text seems to not work.

This is expected. RSA only operates on short inputs. If you want to encrypt a long message with RSA, you need to do one of two things:

  1. Break your message into several distinct chunks and encrypt them separately. This is slow, inefficient, and insecure. (Attackers can drop or reorder chunks.)
  2. Use a secure construction combining RSA and AES, like so.

Thus, you end up with something like this:

  • Encryption
    1. Generate a random 32-byte key, k.
    2. Encrypt k with your RSA public key to get C.
    3. Calculate the HMAC-SHA256(C, k) to get the message key m.
    4. Encrypt your message (P) with m, using AES-256-GCM to get D.
    5. Return C and D.
  • Decryption
    1. Generate a random dummy key, which we'll call k'.
    2. Decrypt C using your RSA private key, to obtain k (one-time AES key).
    3. If step 2 failed, use a constant-time algorithm to swap k out for k'.
    4. Calculate the HMAC-SHA256(C, k) to get the message key m.
    5. Decrypt D using m.
    6. Return the decrypted plaintext (or fail because of the authentication tag).

I read to use openssl_seal/open.. when I demoed the code on a test page it works great.. when I put it into practice with mysql its not working the way its supposed to..

First, consider using libsodium instead.

Whether or not you continue to use OpenSSL, you probably want to base64-encode your output (and make sure you're storing data in a text field rather than a short varchar).

Upvotes: 2

Related Questions