openssl_private_encrypt()
(PHP 4 >= 4.0.6, PHP 5, PHP 7)
使用私钥加密数据
说明
openssl_private_encrypt(string $data,string &$crypted, mixed $key[,int $padding= OPENSSL_PKCS1_PADDING]): bool
openssl_private_encrypt()使用私钥$key加密数据$data并且将结果保存至变量$crypted中。加密后的数据可以通过openssl_public_decrypt()函数来解密。
该函数用来签名数据(或者哈希)让别人相信数据并不是其他人写的。
参数
- $data
- $crypted
- $key
- $padding
$padding可以是如下之一:
OPENSSL_PKCS1_PADDING
,OPENSSL_NO_PADDING
.
返回值
成功时返回TRUE
,或者在失败时返回FALSE
。
参见
openssl_public_encrypt()
使用公钥加密数据openssl_public_decrypt()
使用公钥解密数据
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; } ?>
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; } ?>
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"; ?>
<?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 !
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ƒ¦ª-TÜ++ßYG?-úö¦}9+k8OJn_?¦x?¦ dó+aév.cå?-ï`,¦?·5u¦p%Z²¤ÜI?û ¼ ( ¦E@n¥u?7Fëµ¥+-M¼ìk?7¥;t?8[j¼ñrƒ¦ª-TÜ++ßYG?-úö¦}9+k8OJn_?¦x?¦ dó+aév.cå?-ï`,¦?·5u¦p%Z²¤Ü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Ѫ*¦?·UÿoPÖFq -? O{²¦á|,äIN)+_-öF+*¦{|??G-??£/?¬±"PFL hT!¡_ #+£-íßÿo»¢äSs+üSnäÖ-(¦ëIkl[¤¦=?í?Ç+Uy·N,=b=+¦TàmeNo¦A~ùÑtü¦@ÿ½»¦SV5Ѫ*¦?·UÿoPÖFq -? O{²¦á|,äIN)+_-öF+*¦{|??G-??£/?¬±"PFL->this is a test for crypting