openssl_public_decrypt

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

openssl_public_decryptDecrypts data with public key

说明

bool openssl_public_decrypt ( string $data , string &$decrypted , mixed $key [, int $padding = OPENSSL_PKCS1_PADDING ] )

openssl_public_decrypt() decrypts data that was previous encrypted via openssl_private_encrypt() and stores the result into decrypted.

You can use this function e.g. to check if the message was written by the owner of the private key.

参数

data

decrypted

key

key must be the public key corresponding that was used to encrypt the data.

padding

padding can be one of OPENSSL_PKCS1_PADDING, OPENSSL_NO_PADDING.

返回值

成功时返回 TRUE, 或者在失败时返回 FALSE

参见

User Contributed Notes

Hernanibus 31-Aug-2016 11:54
Just a little note on  [P.Peyremorte]'s note in manual's openssl_private_encrypt.

"- openssl_private_encrypt can encrypt a maximum of 117 chars at one time."

This depends on the length of $key:

- For a 1024 bit key length => max number of chars (bytes) to encrypt = 1024/8 - 11(when padding used) = 117 chars (bytes).
- For a 2048 bit key length => max number of chars (bytes) to encrypt = 2048/8 - 11(when padding used) = 245 chars (bytes).
... and so on

By the way, if openssl_private_encrypt fails because of data size you won't get anything but just false as returned value, the same for openssl_public_decrypt() on decryption.

"- the encrypted output string is always 129 char length. If you use base64_encode on the encrypted output, it will give always 172 chars, with the last always "=" (filler)"

This again depends on the length of $key:

- For a 1024 bit key length => encrypted number of raw bytes is always a block of 128 bytes (1024 bits) by RSA design.
- For a 2048 bit key length => encrypted number of raw bytes is always a block of 256 bytes (2048 bits) by RSA design.
... and so on

About base64_encode output length, it depends on what you encode (meaning it depends on the bytes resulting after encryption), but in general the resulting encoded string will be about a 33% bigger (for 128 bytes bout 170 bytes and for 256 bytes about 340 bytes).

I would then generalize a little [P.Peyremorte]'s note by:
<?php
// given the variables as constants:

  //Block size for encryption block cipher
 
private $ENCRYPT_BLOCK_SIZE = 200;// this for 2048 bit key for example, leaving some room

  //Block size for decryption block cipher
 
private $DECRYPT_BLOCK_SIZE = 256;// this again for 2048 bit key

         //For encryption we would use:
 
function encrypt_RSA($plainData, $privatePEMKey)
  {
   
$encrypted = '';
   
$plainData = str_split($plainData, $this->ENCRYPT_BLOCK_SIZE);
    foreach(
$plainData as $chunk)
    {
     
$partialEncrypted = '';

     
//using for example OPENSSL_PKCS1_PADDING as padding
     
$encryptionOk = openssl_private_encrypt($chunk, $partialEncrypted, $privatePEMKey, OPENSSL_PKCS1_PADDING);

      if(
$encryptionOk === false){return false;}//also you can return and error. If too big this will be false
     
$encrypted .= $partialEncrypted;
    }
    return
base64_encode($encrypted);//encoding the whole binary String as MIME base 64
 
}

        
//For decryption we would use:
 
protected function decrypt_RSA($publicPEMKey, $data)
  {
   
$decrypted = '';

   
//decode must be done before spliting for getting the binary String
   
$data = str_split(base64_decode($data), $this->DECRYPT_BLOCK_SIZE);

    foreach(
$data as $chunk)
    {
     
$partial = '';

     
//be sure to match padding
     
$decryptionOK = openssl_public_decrypt($chunk, $partial, $publicPEMKey, OPENSSL_PKCS1_PADDING);

      if(
$decryptionOK === false){return false;}//here also processed errors in decryption. If too big this will be false
     
$decrypted .= $partial;
    }
    return
$decrypted;
  }
?>
wfredkNOSPAM at L5DevelopmentNOSPAM dot com 09-Mar-2002 12:52
Encrypt using private key, decrypt using public key.

Use this for posting signed messages:  Anyone with access to
your public key can read it, but they can't create one with
your signature.

<?php
echo "Source: $source";
$fp=fopen("/path/to/private.key","r");
$priv_key=fread($fp,8192);
fclose($fp);
// $passphrase is required if your key is encoded (suggested)
$res = openssl_get_privatekey($priv_key,$passphrase);
/*
 * NOTE:  Here you use the returned resource value
 */
openssl_private_encrypt($source,$crypttext,$res);
echo
"String crypted: $crypttext";

$fp=fopen ("/path/to/certificate.crt","r");
$pub_key=fread($fp,8192);
fclose($fp);
openssl_get_publickey($pub_key);
/*
 * NOTE:  Here you use the $pub_key value (converted, I guess)
 */
openssl_public_decrypt($crypttext,$newsource,$pub_key);
echo
"String decrypt : $newsource";
?>
billnet at tiscalinet dot it 28-Jan-2002 07:41
<?php
$fp
=fopen ("/path/to/certificato.pem");
$pub_key=fread ($fp,8192);
openssl_get_publickey ($pub_key);
openssl_public_decrypt ($source,$finaltext,$pub_key);
echo
"String decrypt : $finaltext";
?>