• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • openssl_public_decrypt()

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

    使用公钥解密数据

    说明

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

    openssl_public_decrypt()解密先前由openssl_private_encrypt()加密的数据$data并且将结果保存至变量$decrypted中。

    你可以用该函数来校验消息是否是私钥拥有者写的。

    参数

    $data
    $decrypted
    $key

    $key必须是和用来加密数据的私钥配对的公钥。

    $padding

    $padding可以是如下至OPENSSL_PKCS1_PADDING,OPENSSL_NO_PADDING.

    返回值

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

    参见

    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;
     }
    ?>
    
    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/certificato.pem");
    $pub_key=fread ($fp,8192);
    openssl_get_publickey ($pub_key);
    openssl_public_decrypt ($source,$finaltext,$pub_key);
    echo "String decrypt : $finaltext";
    ?>