openssl_private_encrypt

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

openssl_private_encryptEncrypts data with private key

说明

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

openssl_private_encrypt() encrypts data with private key and stores the result into crypted. Encrypted data can be decrypted via openssl_public_decrypt().

This function can be used e.g. to sign data (or its hash) to prove that it is not written by someone else.

参数

data

crypted

key

padding

padding can be one of OPENSSL_PKCS1_PADDING, OPENSSL_NO_PADDING.

返回值

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

参见

User Contributed Notes

Hernanibus 31-Aug-2016 11:52
Just a little note on  [P.Peyremorte]'s note.

"- 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;
  }
?>
P.Peyremorte 16-Mar-2016 03:17
A trick not mentioned in manual to know :

- openssl_private_encrypt can encrypt a maximum of 117 chars at one time.
- 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).

So, to encode a longer stream input you have to use something like :
<?php
$RawData
= ... ; //Your input data to encode

$PartialData = '';
$EncodedData = '';
$Split = str_split($RawData , 117);
ForEach(
$Split as $Part)
{
 
openssl_private_encrypt($Part, $PartialData, $PrivateKey);
 
$EncodedData .= base64_encode($PartialData);
}
?>

and then, to decode :

<?php
$OriginalData
= '';
$Split = str_split($EncodedData , 172);
ForEach(
$Split as $Part)
{
 
openssl_private_decrypt(base64_decode($Part), $PartialData, $PublicKey);
 
$OriginalData .= $PartialData;
}
?>
adityasingh at techknowtrends dot com 03-Apr-2012 06:18
Here is a over simplified version of using the crypt capabilities for getting started:

$res = openssl_pkey_new();

// Get private key
openssl_pkey_export($res, $privkey);

// Get public key
$pubkey = openssl_pkey_get_details($res);
$pubkey = $pubkey["key"];
var_dump($privkey);
var_dump($pubkey);

// get some text from command line to work with
$tocrypt = trim(fgets(STDIN));

// some variables to work with
$encryptedviaprivatekey = ""; //holds text encrypted with the private key
$decryptedviapublickey = ""; // holds text which was decrypted by the public key after being encrypted with the private key, should be same as $tocrypt
$encryptedviapublickey = ""; // holds text that was encrypted with the public key
$decryptedviaprivatekey = ""; // holds text that was decrypted with the private key after being encrypted with the public key, should be the same as $tocrypt

openssl_private_encrypt($tocrypt, $encryptedviaprivatekey, $privkey);
echo $tocrypt . "->" . $encryptedviaprivatekey;
echo "\n\n";
openssl_public_decrypt($encryptedviaprivatekey, $decryptedviapublickey, $pubkey);
echo $encryptedviaprivatekey . "->" . $decryptedviapublickey;
echo "\n\n";

openssl_public_encrypt($tocrypt,$encryptedviapublickey, $pubkey);
echo $tocrypt . "->" . $encryptedviapublickey;
echo "\n\n";
openssl_private_decrypt($encryptedviapublickey, $decryptedviaprivatekey, $privkey);
echo $encryptedviapublickey . "->" . $decryptedviaprivatekey;

Output:

string(887) "-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCy745x8AqGKlTWBu2Ub80boPaQxo/midZ4LHZ0zbPpiCAfkADN
VYSe8OckPKutdjPX7SNAx66PgQRH1xrz1gysbRrf8K/mA0LQ00MKBFaFottWt5cC
IaUS9zvCgPw7prwng3hkGShnvTSMXiKFyt1E3RTvpXRk0u46D6hKiy+TSQIDAQAB
AoGBAJe1jjNCDtoz19vi4doBdIhhT8vt3iHbafBX2lMr+MceeAXqpRNy10+e9op9
uh0G4+vGDialZnYbMBLs6Ngl+nVnzn+cN1MMJ18brgf3biZKzVzK9wmOW4eycWaR
9eLa7/+ns8Cw5GsLJdG+OHR2gXRXU4hzUFdf90UUbP+kuqK1AkEA2X04XznFDNmT
NuhyCixwinlziazJBp/81jjaBhYj3cG0nTF0Gactc/yD0yudbrMqjLBfts+FbG3Z
yFHKrAB/cwJBANKetll3M3aCGsermEK+9hbB8yMihCju6pAwClUNkrAgrm9zU4LP
WkC81RDzXbz+pfIqpopfn34F3+U2iMiOe1MCQCXpTgpLZ631v1Oy8S4U0QlSYnF9
TQ16lfhBsL+e3GGrgnBkTniqS6IMQm5tC+RgFuqvU//p7LgZ7fydRVb2P0ECQFp9
YADuKskmutTAj6lVnCtI5upYgQmJJHQQf8/tBfHwCKHPnbic17zqpGwk80go7Ckw
U98tmDuv0HMNTBVGygsCQALck7VNBRjL9iFzJMFis+alcP1ZC88wOLPvIxYbevUH
c8rZwRqt1aHwaWOoxcVom+tyzRC6gEYoBarmU1bX4No=
-----END RSA PRIVATE KEY-----
"
string(272) "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCy745x8AqGKlTWBu2Ub80boPaQ
xo/midZ4LHZ0zbPpiCAfkADNVYSe8OckPKutdjPX7SNAx66PgQRH1xrz1gysbRrf
8K/mA0LQ00MKBFaFottWt5cCIaUS9zvCgPw7prwng3hkGShnvTSMXiKFyt1E3RTv
pXRk0u46D6hKiy+TSQIDAQAB
-----END PUBLIC KEY-----
"
this is a test for crypting
( |E@n¥u?7F?μ¥+-M?ìk?7¥;t?8[j??r?|a-Tü++?YG?-ú?|}9+k8OJn_?|x?|
dó+aév.c??-?`,|?·5u|p%Z2¤üI?? ?

( |E@n¥u?7F?μ¥+-M?ìk?7¥;t?8[j??r?|a-Tü++?YG?-ú?|}9+k8OJn_?|x?|
dó+aév.c??-?`,|?·5u|p%Z2¤üI?? ?->this is a test for crypting

this is a test for crypting->hT!?_
#+£-í??o?¢?Ss+üSn??-(|?Ikl[¤|=?í??+Uy·N,=b=+|TàmeNo|A~ù?tü|@???|SV5?a*|?·U?oP?Fq
-? O{2|á|,?IN)+_-?F+*|{|??G-??£/??±"PFL

hT!?_
#+£-í??o?¢?Ss+üSn??-(|?Ikl[¤|=?í??+Uy·N,=b=+|TàmeNo|A~ù?tü|@???|SV5?a*|?·U?oP?Fq
-? O{2|á|,?IN)+_-?F+*|{|??G-??£/??±"PFL->this is a test for crypting
wfredkNOSPAM at L5DevelopmentNOSPAM dot com 09-Mar-2002 12:50
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:47
<?php
$fp
=fopen ("/path/to/key.pem","r");
$priv_key=fread ($fp,8192);
fclose($fp);
openssl_get_privatekey ($priv_key);
openssl_private_encrypt($source,$finaltext,$priv_key);
echo
"String crypted: $finaltext";
?>

CIAO !