Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : OpenSSL Functions : openssl_public_encrypt

openssl_public_encrypt

Encrypts data with public key (PHP 4 >= 4.0.6, PHP 5)
bool openssl_public_encrypt ( string data, string &crypted, mixed key [, int padding] )


Code Examples / Notes » openssl_public_encrypt

rstinnett

To store the encrypted data in a MySQL database, you first have to encode the data so it can safely be written. You can use a blob type for this, but it can make SELECTs really nasty. The easiest way I have found to do this is with base64_encode and base64_decode. The following example using code from a previous example and split into encrypt and decrypt functions.
function EncryptData($source)
{
 $fp=fopen("/etc/httpd/conf/ssl.crt/server.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_encrypt($source,$crypttext,$pub_key);
 return(base64_encode($crypttext));
}
function DecryptData($source)
{
 #print("number : $number");
 $fp=fopen("/etc/httpd/conf/ssl.key/server.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
  */
 $decoded_source = base64_decode($source);
 openssl_private_decrypt($decoded_source,$newsource,$res);
 return($newsource);
}
Just use the return values to store the encrypted data or display the decrypted data.


webmaster

This example worked for me:
RedHat 7.2 / php 4.2.2 / Apache 1.3.7
// STEP 1: Encryption with Public Key (you will need Private Key to decrypt - see step2).
$string="Some Important Data";
$fp=fopen ("cert.pem","r");
$pub_key=fread ($fp,8192);
fclose($fp);
$PK="";
$PK=openssl_get_publickey($pub_key);
if (!$PK) {
echo "Cannot get public key";
}
$finaltext="";
openssl_public_encrypt($string,$finaltext,$PK);
if (!empty($finaltext)) {
openssl_free_key($PK);
echo "Encryption OK!";
}else{
echo "Cannot Encrypt";
}
// STEP 2: Decription (Using Private Key)
$fp=fopen ("pk.pem","r");
$priv_key2=fread ($fp,8192);
fclose($fp);
$PK2=openssl_get_privatekey($priv_key2);
$Crypted=openssl_private_decrypt($Data,$Decrypted,$PK2);
if (!$Crypted) {
$MSG.="<p class='error'>Cannot Decrypt ($CCID).";
}else{
   echo "Decrypted Data: " . $Decrypted;
}


kenashkov

The encrypted data can be stored in MySQL without use of base64. It must be properly escaped with mysql_real_escape_string(), and then saved to BLOB column. (In fact - this function must be used every time when you insert binary data in MySQL).

adrian

T. Horsten explained the size limits on raw encryption. Here are two functions to encrypt/decrypt larger data when you can't use the envelope functions:
function ssl_encrypt($source,$type,$key){
//Assumes 1024 bit key and encrypts in chunks.
$maxlength=117;
$output='';
while($source){
 $input= substr($source,0,$maxlength);
 $source=substr($source,$maxlength);
 if($type=='private'){
   $ok= openssl_private_encrypt($input,$encrypted,$key);
 }else{
   $ok= openssl_public_encrypt($input,$encrypted,$key);
 }

 $output.=$encrypted;
}
return $output;
}
function ssl_decrypt($source,$type,$key){
// The raw PHP decryption functions appear to work
// on 128 Byte chunks. So this decrypts long text
// encrypted with ssl_encrypt().
$maxlength=128;
$output='';
while($source){
 $input= substr($source,0,$maxlength);
 $source=substr($source,$maxlength);
 if($type=='private'){
   $ok= openssl_private_decrypt($input,$out,$key);
 }else{
   $ok= openssl_public_decrypt($input,$out,$key);
 }

 $output.=$out;
}
return $output;
}


pigo

openssl_public_encrypt and openssl_private_encrypt can't encrypt large data . so I write a class . this class can encrypt large data and decrypt.
look url : http://pigo.pigo.idv.tw/opensslcrypt.phps


jeff

It looks like there is a limit on the size of the string to be encrypted: about 50 characters.
This is due to the fact that the implementation allocates an output buffer of size EVP_PKEY_size(pkey), which is totally arbitrary and unrelated to the size of the input.  Also, it's not using a cipher envelope approach.  It's just RSAing the input string.


chsnyder

In comment below, Jeff says the input to this function is limited to "about 50 characters". On my PHP5 build, the limit is 117 characters (936 bits, strange number).
That's because public key encryption is CPU intensive, and meant to be used on short values. The idea is to use this function to encrypt a secret key that is in turn used to encrypt data using a more efficient algorithm, such as RC4 or TripleDES. The recipient uses their private key to decrypt the secret, and can then decrypt the data.
The openssl_seal() and openssl_open() functions do this internally, and are very well documented. You should probably use them instead.


jeff

I figured it out.  This function is not intended for general encryption and decryption.  For that, you want openssl_seal() and openssl_open().

hromi

function description is wrong, you have to switch crypttext and text if you want it to work
this is correct:
bool openssl_public_encrypt ( string crypted, string data, mixed key [, int padding])


wfredknospam

Encrypt using public key, decrypt using private key.
Use this to store stuff in your database: Unless someone
has your private key, the database contents are useless.
Also, use this for sending to a specific individual:  Get
their public key, encrypt the message, only they can use
their private key to decode it.
<?php
echo "Source: $source";
$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_encrypt($source,$crypttext,$pub_key);
echo "String crypted: $crypttext";
$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_decrypt($crypttext,$newsource,$res);
echo "String decrypt : $newsource";
?>


lonewolf

Easy way:
<?php
$publicKey = "file://path/to/public/key-crt.pem";
$plaintext = "String to encrypt";
openssl_public_encrypt($plaintext, $encrypted, $publicKey);
echo $encrypted;   //encrypted string
?>


thomas horsten

chsnyder writes that the data is limited to 936 bits in his implementation.
Actually, it has nothing to do with RSA being CPU intensive, RAM or anything of the sort.
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.
However, the PKCS#1 standard, which OpenSSL uses, specifies a padding scheme (so you can encrypt smaller quantities without losing security), and that padding scheme takes a minimum of 11 bytes (it will be longer if the value you're encrypting is smaller). So the highest number of bits you can encrypt with a 1024-bit key is 936 bits because of this (unless you disable the padding by adding the OPENSSL_NO_PADDING flag, in which case you can go up to 1023-1024 bits). With a 2048-bit key it's 1960 bits instead.
But as chsnyder correctly wrote, the normal application of a public key encryption algorithm is to store a key or a hash of the data you want to respectively encrypt or sign. A hash is typically 128-256 bits (the PHP sha1() function returns a 160 bit hash). And an AES key is 128 to 256 bits. So either of those will comfortably fit inside a single RSA encryption.


Change Language


Follow Navioo On Twitter
openssl_csr_export_to_file
openssl_csr_export
openssl_csr_get_public_key
openssl_csr_get_subject
openssl_csr_new
openssl_csr_sign
openssl_error_string
openssl_free_key
openssl_get_privatekey
openssl_get_publickey
openssl_open
openssl_pkcs12_export_to_file
openssl_pkcs12_export
openssl_pkcs12_read
openssl_pkcs7_decrypt
openssl_pkcs7_encrypt
openssl_pkcs7_sign
openssl_pkcs7_verify
openssl_pkey_export_to_file
openssl_pkey_export
openssl_pkey_free
openssl_pkey_get_details
openssl_pkey_get_private
openssl_pkey_get_public
openssl_pkey_new
openssl_private_decrypt
openssl_private_encrypt
openssl_public_decrypt
openssl_public_encrypt
openssl_seal
openssl_sign
openssl_verify
openssl_x509_check_private_key
openssl_x509_checkpurpose
openssl_x509_export_to_file
openssl_x509_export
openssl_x509_free
openssl_x509_parse
openssl_x509_read
eXTReMe Tracker