Encrypt and Decrypt text with RSA in PHP

rsa encryption and decryption in php example
laravel rsa encryption
php encrypt and decrypt
php rsa->loadkey
how to implement rsa in php
php rsa modulus exponent
openssl_public_encrypt(): key parameter is not a valid public key
encryption and decryption project in php

IS there any class for PHP 5.3 that will provide text encrypting/decrypting with RSA without padding?

I've got private and public key, p,q and modulus.

You can use phpseclib, a pure PHP RSA implementation:

<?php
include('Crypt/RSA.php');

$privatekey = file_get_contents('private.key');

$rsa = new Crypt_RSA();
$rsa->loadKey($privatekey);

$plaintext = new Math_BigInteger('aaaaaa');
echo $rsa->_exponentiate($plaintext)->toBytes();
?>

openssl_public_encrypt - Manual, Encrypted data can be decrypted via openssl_private_decrypt(). Basically when you encrypt something using an RSA key (whether public or private), value is text and passes the text to openssl_pkey_get_public() to get a valid resource. This class is a pure PHP implementation of the RSA public key encryption algorithm. It can generate the public and private keys from two prime numbers. The public key should be used to encrypt the data. Only the private key can be used to decrypt the data encrypted with the public key. It has also digital signature functionality.

Security warning: This code snippet is vulnerable to Bleichenbacher's 1998 padding oracle attack. See this answer for better security.

class MyEncryption
{

    public $pubkey = '...public key here...';
    public $privkey = '...private key here...';

    public function encrypt($data)
    {
        if (openssl_public_encrypt($data, $encrypted, $this->pubkey))
            $data = base64_encode($encrypted);
        else
            throw new Exception('Unable to encrypt data. Perhaps it is bigger than the key size?');

        return $data;
    }

    public function decrypt($data)
    {
        if (openssl_private_decrypt(base64_decode($data), $decrypted, $this->privkey))
            $data = $decrypted;
        else
            $data = '';

        return $data;
    }
}

openssl_private_decrypt - Manual, openssl_private_decrypt ( string $data , string &$decrypted , mixed $key [, int $​padding Encrypt using public key, decrypt using private key. Use this to store  Basically when you encrypt something using an RSA key (whether public or private), the encrypted value must be smaller than the key (due to the maths used to do the actual encryption). So if you have a 1024-bit key, in theory you could encrypt any 1023-bit value (or a 1024-bit value smaller than the key) with that key.

No application written in 2017 (or thereafter) that intends to incorporate serious cryptography should use RSA any more. There are better options for PHP public-key cryptography.

There are two big mistakes that people make when they decide to encrypt with RSA:

  1. Developers choose the wrong padding mode.
  2. Since RSA cannot, by itself, encrypt very long strings, developers will often break a string into small chunks and encrypt each chunk independently. Sort of like ECB mode.
The Best Alternative: sodium_crypto_box_seal() (libsodium)
$keypair = sodium_crypto_box_keypair();
$publicKey = sodium_crypto_box_publickey($keypair);
// ...
$encrypted = sodium_crypto_box_seal(
    $plaintextMessage,
    $publicKey
);
// ...
$decrypted = sodium_crypto_box_seal_open(
    $encrypted,
    $keypair
);

Simple and secure. Libsodium will be available in PHP 7.2, or through PECL for earlier versions of PHP. If you need a pure-PHP polyfill, get paragonie/sodium_compat.

Begrudgingly: Using RSA Properly

The only reason to use RSA in 2017 is, "I'm forbidden to install PECL extensions and therefore cannot use libsodium, and for some reason cannot use paragonie/sodium_compat either."

Your protocol should look something like this:

  1. Generate a random AES key.
  2. Encrypt your plaintext message with the AES key, using an AEAD encryption mode or, failing that, CBC then HMAC-SHA256.
  3. Encrypt your AES key (step 1) with your RSA public key, using RSAES-OAEP + MGF1-SHA256
  4. Concatenate your RSA-encrypted AES key (step 3) and AES-encrypted message (step 2).

Instead of implementing this yourself, check out EasyRSA.

Further reading: Doing RSA in PHP correctly.

PHP – RSA (Public-Private Key Encryption Decryption) – Developer , Struggled really hard to find a good example to encrypt and decrypt a a string using OpenSSL. PHP – RSA (Public-Private Key Encryption Decryption) This is not required but can be useful if the encrypted text is to be  PHP: Basic two-way encryption Tweet 0 Shares 0 Tweets 6 Comments. While the trusty old PHP crypt function is perfect for encrypting and authenticating passwords, the hash it creates is one-way and doesn't allow for decryption.

If you are using PHP >= 7.2 consider using inbuilt sodium core extension for encrption.

It is modern and more secure. You can find more information here - http://php.net/manual/en/intro.sodium.php. and here - https://paragonie.com/book/pecl-libsodium/read/00-intro.md

Example PHP 7.2 sodium encryption class -

<?php

/**
 * Simple sodium crypto class for PHP >= 7.2
 * @author MRK
 */
class crypto {

    /**
     * 
     * @return type
     */
    static public function create_encryption_key() {
        return base64_encode(sodium_crypto_secretbox_keygen());
    }

    /**
     * Encrypt a message
     * 
     * @param string $message - message to encrypt
     * @param string $key - encryption key created using create_encryption_key()
     * @return string
     */
    static function encrypt($message, $key) {
        $key_decoded = base64_decode($key);
        $nonce = random_bytes(
                SODIUM_CRYPTO_SECRETBOX_NONCEBYTES
        );

        $cipher = base64_encode(
                $nonce .
                sodium_crypto_secretbox(
                        $message, $nonce, $key_decoded
                )
        );
        sodium_memzero($message);
        sodium_memzero($key_decoded);
        return $cipher;
    }

    /**
     * Decrypt a message
     * @param string $encrypted - message encrypted with safeEncrypt()
     * @param string $key - key used for encryption
     * @return string
     */
    static function decrypt($encrypted, $key) {
        $decoded = base64_decode($encrypted);
        $key_decoded = base64_decode($key);
        if ($decoded === false) {
            throw new Exception('Decryption error : the encoding failed');
        }
        if (mb_strlen($decoded, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)) {
            throw new Exception('Decryption error : the message was truncated');
        }
        $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
        $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');

        $plain = sodium_crypto_secretbox_open(
                $ciphertext, $nonce, $key_decoded
        );
        if ($plain === false) {
            throw new Exception('Decryption error : the message was tampered with in transit');
        }
        sodium_memzero($ciphertext);
        sodium_memzero($key_decoded);
        return $plain;
    }

}

Sample Usage -

<?php 

$key = crypto::create_encryption_key();

$string = 'Sri Lanka is a beautiful country !';

echo $enc = crypto::encrypt($string, $key); 
echo crypto::decrypt($enc, $key);

PHP Extension RSA Encrypt and Decrypt Strings, (PHP Extension) RSA Encrypt and Decrypt Strings. PHP Extension sample code to RSA public-key encrypt and decrypt strings using public and private keys. Encrypt & Decrypt Text Online. In cryptography, encryption is the process of transforming information (referred to as plaintext) using an algorithm (called cipher) to make it unreadable to anyone except those possessing special knowledge, usually referred to as a key. The result of the process is encrypted information (in cryptography, referred to as ciphertext).

Yes. Look at http://jerrywickey.com/test/testJerrysLibrary.php

It gives sample code examples for RSA encryption and decryption in PHP as well as RSA encryption in javascript.

If you want to encrypt text instead of just base 10 numbers, you'll also need a base to base conversion. That is convert text to a very large number. Text is really just writing in base 63. 26 lowercase letters plus 26 uppercase + 10 numerals + space character. The code for that is below also.

The $GETn parameter is a file name that holds keys for the cryption functions. If you don't figure it out, ask. I'll help.

I actually posted this whole encryption library yesterday, but Brad Larson a mod, killed it and said this kind of stuff isn't really what Stack Overflow is about. But you can still find all the code examples and the whole function library to carry out client/server encryption decryption for AJAX at the link above.

function RSAencrypt( $num, $GETn){
    if ( file_exists( 'temp/bigprimes'.hash( 'sha256', $GETn).'.php')){
        $t= explode( '>,', file_get_contents('temp/bigprimes'.hash( 'sha256', $GETn).'.php'));
        return JL_powmod( $num, $t[4], $t[10]); 
    }else{
        return false;
    }
}

function RSAdecrypt( $num, $GETn){
    if ( file_exists( 'temp/bigprimes'.hash( 'sha256', $GETn).'.php')){
        $t= explode( '>,', file_get_contents('temp/bigprimes'.hash( 'sha256', $GETn).'.php'));
        return JL_powmod( $num, $t[8], $t[10]);     
    }else{
        return false;
    }
}

function JL_powmod( $num, $pow, $mod) {
    if ( function_exists('bcpowmod')) {
        return bcpowmod( $num, $pow, $mod);
    }
    $result= '1';
    do {
        if ( !bccomp( bcmod( $pow, '2'), '1')) {
            $result = bcmod( bcmul( $result, $num), $mod);
        }
       $num = bcmod( bcpow( $num, '2'), $mod);

       $pow = bcdiv( $pow, '2');
    } while ( bccomp( $pow, '0'));
    return $result;
}

function baseToBase ($message, $fromBase, $toBase){
    $from= strlen( $fromBase);
    $b[$from]= $fromBase; 
    $to= strlen( $toBase);
    $b[$to]= $toBase; 

    $result= substr( $b[$to], 0, 1);

    $f= substr( $b[$to], 1, 1);

    $tf= digit( $from, $b[$to]);

    for ($i=strlen($message)-1; $i>=0; $i--){
        $result= badd( $result, bmul( digit( strpos( $b[$from], substr( $message, $i, 1)), $b[$to]), $f, $b[$to]), $b[$to]);
        $f= bmul($f, $tf, $b[$to]);
    }
    return $result;
} 

function digit( $from, $bto){   
    $to= strlen( $bto);
    $b[$to]= $bto; 

    $t[0]= intval( $from);
    $i= 0;
    while ( $t[$i] >= intval( $to)){
        if ( !isset( $t[$i+1])){ 
            $t[$i+1]= 0;
        }
        while ( $t[$i] >= intval( $to)){
            $t[$i]= $t[$i] - intval( $to);
            $t[$i+1]++;
        }
        $i++;
    }

    $res= '';
    for ( $i=count( $t)-1; $i>=0; $i--){ 
        $res.= substr( $b[$to], $t[$i], 1);
    }
    return $res;
}   

function badd( $n1, $n2, $nbase){
    $base= strlen( $nbase);
    $b[$base]= $nbase; 

    while ( strlen( $n1) < strlen( $n2)){
        $n1= substr( $b[$base], 0, 1) . $n1;
    }
    while ( strlen( $n1) > strlen( $n2)){
        $n2= substr( $b[$base], 0, 1) . $n2;
    }
    $n1= substr( $b[$base], 0, 1) . $n1;    
    $n2= substr( $b[$base], 0, 1) . $n2;
    $m1= array();
    for ( $i=0; $i<strlen( $n1); $i++){
        $m1[$i]= strpos( $b[$base], substr( $n1, (strlen( $n1)-$i-1), 1));
    }   
    $res= array();
    $m2= array();
    for ($i=0; $i<strlen( $n1); $i++){
        $m2[$i]= strpos( $b[$base], substr( $n2, (strlen( $n1)-$i-1), 1));
        $res[$i]= 0;
    }           
    for ($i=0; $i<strlen( $n1)  ; $i++){
        $res[$i]= $m1[$i] + $m2[$i] + $res[$i];
        if ($res[$i] >= $base){
            $res[$i]= $res[$i] - $base;
            $res[$i+1]++;
        }
    }
    $o= '';
    for ($i=0; $i<strlen( $n1); $i++){
        $o= substr( $b[$base], $res[$i], 1).$o;
    }   
    $t= false;
    $o= '';
    for ($i=strlen( $n1)-1; $i>=0; $i--){
        if ($res[$i] > 0 || $t){    
            $o.= substr( $b[$base], $res[$i], 1);
            $t= true;
        }
    }
    return $o;
}
function bmul( $n1, $n2, $nbase){
    $base= strlen( $nbase);
    $b[$base]= $nbase; 

    $m1= array();
    for ($i=0; $i<strlen( $n1); $i++){
        $m1[$i]= strpos( $b[$base], substr($n1, (strlen( $n1)-$i-1), 1));
    }   
    $m2= array();
    for ($i=0; $i<strlen( $n2); $i++){
        $m2[$i]= strpos( $b[$base], substr($n2, (strlen( $n2)-$i-1), 1));
    }           
    $res= array();
    for ($i=0; $i<strlen( $n1)+strlen( $n2)+2; $i++){
        $res[$i]= 0;
    }
    for ($i=0; $i<strlen( $n1)  ; $i++){
        for ($j=0; $j<strlen( $n2)  ; $j++){
            $res[$i+$j]= ($m1[$i] * $m2[$j]) + $res[$i+$j];
            while ( $res[$i+$j] >= $base){
                $res[$i+$j]= $res[$i+$j] - $base;
                $res[$i+$j+1]++;
            }
        }
    }
    $t= false;
    $o= '';
    for ($i=count( $res)-1; $i>=0; $i--){
        if ($res[$i]>0 || $t){  
            $o.= substr( $b[$base], $res[$i], 1);
            $t= true;
        }
    }
    return $o;
}

PHP, RSA, Encrypt/Decrypt · GitHub, PHP, RSA, Encrypt/Decrypt. gistfile1.txt. <?php openssl rsa -in private.pem -​outform PEM -pubout -out public.pem. $data = "String to encrypt";. Simple PHP encrypt and decrypt using OpenSSL. GitHub Gist: instantly share code, notes, and snippets.

RSA: Encrypt and decrypt data with RSA public keys, RSA is a very important encryption algorithm. It allows securely transmitting data encrypted with a private key that can only be decrypted with a public key. There is​  In PHP, Encryption and Decryption of a string is possible using one of the Cryptography Extensions called OpenSSL function for encrypt and decrypt. openssl_encrypt() Function: The openssl_encrypt() function is used to encrypt the data.

RSA cryptography in PHP (How To?) – bckurera's thoughts, the RSA encryption/ decryption handling in your PHP development. <?php. //​create keys. myRSA::createKeyPair(1024);. //Text to encrypt. Learn how to use different functions to encrypt and decrypt strings in PHP. Functions discussed are: mcrypt_ecb, mcrypt_encrypt and mcrypt_generic. Source Co

Everything You Know About Public-Key Encryption in PHP is Wrong , In PHP, most RSA implementations will make use of two functions to actually encrypt/decrypt data:. Encrypt Key1 -> Decrypt Key2 -> Encrypt Key3 and both .NET and PHP's mcrypt do this the same way. The problem arises in short key mode on .NET, since 128 bits is only two 64 bit DES keys The algorithm that they use then is: Encrypt Key1 -> Decrypt Key2 -> Encrypt Key1 mcrypt does not have this mode of operation natively.

Comments
  • @ScottArciszewski - the only thing I can possibly imagine that makes you say that is that phpseclib 1.0 and 2.0 use sha1 as the default hash. OAEP / PSS are the default modes for all versions of phpseclib and those are plenty secure. And if you want to change the hash you can do so by doing $rsa->setHash('sha256') or whatever. Further, the master branch (which will be 3.0 in the future as I understand it) has sha256 as the default hash. 1.0 and 2.0's defaulting to sha1 will never change as that'd constitute a BC break.
  • "OAEP / PSS are the default modes for all versions of phpseclib" Okay, I was mistaken on that point. :)
  • I've tried it also but my public key is: (added spaces to avoid website mess) 109120132967399429278860960508995541528237502902798129123468757937266291492576446330739696001110 6039072308886100726558188253585034290 57592827629436413108566029093628 2126359538366865626758497206207862794310902180176810615217550567108238764764442605581471797071 19674283982419152118103759076030616683978566631413 and it says: error:0906D06c:PEM routines:PEM_read_bio:no start line
  • It works well at my end u can change this base64 _decode to base32_decode and try.
  • The only accepted version. Why do people make it themselves so hard.
  • Thank you Scott for sharing your very valuable knowledge with the community!
  • the whole $GETn and file_get~~ looks like a bad idea.. why the f do you do this? and if you really need to put something in temporary files, tmpfile() with an static array where sha256 is the key, maybe?
  • I use files because using session prevents concurrent iteration of the prime number generator and tmpfile doesn't persist through multiple calls.
  • "tmpfile doesn't persist through multiple calls" sure it can -> static $tmpfiles=array(); if(empty($tmpfiles[hash('sha256',$GETn)])){ $tmpfiles[hash('sha256')]=tmpfile(); }
  • Could you add a security disclaimer telling people not to use this? Textbook RSA is not semantically secure without padding.
  • The prose in this otherwise code-only answer actually makes it look more like a bad question. "I have a problem. Code." Please make the answering part more obvious and consider explaining the core of your code. Formatting so that horizontal scrolling is not necessary would then be just a nice touch.