openssl_public_decrypt

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

openssl_public_decrypt使用公钥解密数据

描述

openssl_public_decrypt(
    string $data,
    #[\SensitiveParameter] string &$decrypted_data,
    OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key,
    int $padding = OPENSSL_PKCS1_PADDING
): bool

openssl_public_decrypt() 解密先前通过 openssl_private_encrypt() 加密的数据 data,并将结果存储到 decrypted_data 中。

例如,您可以使用此函数来检查消息是否是由私钥所有者编写的。

参数

data

decrypted_data

public_key

public_key 必须是用于加密数据​​的相应公钥。

padding

padding 可以是 OPENSSL_PKCS1_PADDINGOPENSSL_NO_PADDING 之一。

返回值

成功时返回 true,失败时返回 false

更新日志

版本 描述
8.0.0 public_key 现在接受 OpenSSLAsymmetricKeyOpenSSLCertificate 实例;以前,接受类型为 OpenSSL keyOpenSSL X.509resource

另请参见

添加备注

用户贡献的备注 3 条备注

Hernanibus
7 年前
只是在 openssl_private_encrypt 手册中的 [P.Peyremorte] 的备注中作一个小小的补充。

“- openssl_private_encrypt 一次最多能加密 117 个字符”。

这取决于 $key 的长度

- 对于长度为 1024 bit 的密钥 => 可加密的最大字符(字节)数 = 1024/8 - 11(使用填充时)= 117 个字符(字节)。
- 对于长度为 2048 bit 的密钥 => 可加密的最大字符(字节)数 = 2048/8 - 11(使用填充时)= 245 个字符(字节)。
... 等等

顺便说一下,如果 openssl_private_encrypt 因数据大小而失败,您不会得到任何东西,只会得到 false 作为返回值,解密时的 openssl_public_decrypt() 也是如此。

“- 加密后的输出字符串始终为 129 个字符。如果您对加密后的输出使用 base64_encode,它始终会给出 172 个字符,最后一个始终为“=”(填充符)”

这又取决于 $key 的长度

- 对于长度为 1024 bit 的密钥 => 根据 RSA 设计,加密的原始字节数始终是一个 128 字节(1024 bit)块。
- 对于长度为 2048 bit 的密钥 => 根据 RSA 设计,加密的原始字节数始终是一个 256 字节(2048 bit)块。
... 等等

关于 base64_encode 输出长度,它取决于您编码的内容(即它取决于加密后产生的字节),但通常情况下,产生的编码字符串将大约大 33%(对于 128 字节约 170 字节,对于 256 字节约 340 字节)。

然后我将对 [P.Peyremorte] 的注释进行一点概括
<?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
22 年前
使用私钥加密,使用公钥解密。

使用此方法发布签名消息:任何有权访问
您公钥的人都可以读取它,但他们无法使用它创建
您的签名。

<?php
echo "源: $source";
$fp=fopen("/path/to/private.key","r");
$priv_key=fread($fp,8192);
fclose($fp);
// 您的密钥被编码(建议),则需要 $passphrase
$res = openssl_get_privatekey($priv_key,$passphrase);
/*
* 注释:此处使用已返回的资源值
*/
openssl_private_encrypt($source,$crypttext,$res);
echo
"加密的字符串: $crypttext";

$fp=fopen ("/path/to/certificate.crt","r");
$pub_key=fread($fp,8192);
fclose($fp);
openssl_get_publickey($pub_key);
/*
* 注释:此处使用 $pub_key 值(我猜是已转换的值)
*/
openssl_public_decrypt($crypttext,$newsource,$pub_key);
echo
"解密的字符串 : $newsource";
?>
billnet at tiscalinet dot it
22 年前
<?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
"解密的字符串 : $finaltext";
?>
To Top