PHP OpenSSL使用字符串公钥进行公钥加密

7

我有一个公钥

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwKMDEDjbP5v/9kcvpQKf
IG3nU5Yid/tUNIeXBSDlxqhTEOKs8iQHXk0T17C4g7KHmrT2hxUomaAa2wwbfL+Z
4ppqvZZ4cu7CO6jaA0HyoBCU96siSuE0mPt8kU/PRA9+nAwu9lu9oYZUiVVJ3D4f
o2bc+jWWL4GGY+PdSlz81ZW5cW/LOmNs9D0jJIxbwNocHxGgJ+xTZ3JKp6AO4MvL
zXyipXu562N8wVc7UIgYYnvr63zFU8vzRL180X5x5MiJbjTYbfLH3z7qINPMZZLv
A5vzJ0HX3J8rG96tmFuUzopCnvf+WVLvaS2T5uMxieK9dfA32CFQp4i3cj39c2b7
NwIDAQAB
-----END PUBLIC KEY-----

公钥存储为base64编码的字符串(在MySQL中,设置为$row['public_key'])

LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF3S01ERURqYlA1di85a2N2cFFLZgpJRzNuVTVZaWQvdFVOSWVYQlNEbHhxaFRFT0tzOGlRSFhrMFQxN0M0ZzdLSG1yVDJoeFVvbWFBYTJ3d2JmTCtaCjRwcHF2Wlo0Y3U3Q082amFBMEh5b0JDVTk2c2lTdUUwbVB0OGtVL1BSQTkrbkF3dTlsdTlvWVpVaVZWSjNENGYKbzJiYytqV1dMNEdHWStQZFNsejgxWlc1Y1cvTE9tTnM5RDBqSkl4YndOb2NIeEdnSit4VFozSktwNkFPNE12TAp6WHlpcFh1NTYyTjh3VmM3VUlnWVludnI2M3pGVTh2elJMMTgwWDV4NU1pSmJqVFliZkxIM3o3cUlOUE1aWkx2CkE1dnpKMEhYM0o4ckc5NnRtRnVVem9wQ252ZitXVkx2YVMyVDV1TXhpZUs5ZGZBMzJDRlFwNGkzY2ozOWMyYjcKTndJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg== 

在PHP中,我正在尝试使用此字符串来加密字符串数据,但当我使用以下代码时,它只是失败了而没有告诉我原因:
$success = openssl_public_encrypt($data, $encrypted, base64_decode($row['public_key']));

当上述代码运行时,$success总是为false,$encrypted为空白。我尝试了将公钥通过openssl_pkey_get_public()传递给openssl_public_encrypt(),但是没有成功。将内容写入文件或存储私钥都不是选项。
有人知道如何解决这个问题吗?(还是说这对其他人有效,只是一个奇怪的服务器问题?) 编辑:由于似乎有些人对我的问题存在困惑,这里是我正在使用的测试代码及其输出。(注意:我已删除了base64编码,只是想看看是否有任何区别)
$pubkey = openssl_get_publickey($row['public_key']);
$publicKey = openssl_pkey_get_details($res);
$encrypted = null;
$success = openssl_public_encrypt($data, $encrypted, $pubkey);
print "\npubkey1 " . $row['public_key'];
print "\npubkey2 " . $pubkey;
print "\npubkey3 " . $publicKey;
print "\npubkey4 " . $publicKey["key"];
print "\nencryption " . ($success ? 'true' : 'false') . ' "' . $encrypted . '"';
$success = openssl_public_encrypt($data, $encrypted, $row['public_key']);
print "\nencryption2 " . ($success ? 'true' : 'false') . ' "' . $encrypted . '"';   

输出:

pubkey1 -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA89FgfElm36q7iAf8frqa
o58naoROsAljaFbmztfnqlmzXfyijK5CNJFdkUCgsu2zGxN7UlGiBOassTd4ijWm
1rz6/ad9fGXplfMGxZxyPCz31VreSWXmTG/PeSIYs1Co+dibV3imYt5jTxfLs7BZ
WsT8nuLxGPw/o/gyKut0Ru+jXI2GgT4s3SylXinn/IbIA497SohqYA7/ViQnBwSL
ZKUysOx2QgBmc9m0viRqDSKNUtDw7+L7bjhlwgZUGr6fxfTuNj9PWo97aPSE74CD
owYYl2ToTboKSjZUszeNwQKpUnlHY/DBkwmYUJ7SAYDY70VNooadN5dZ4ehjdaka
6QIDAQAB
-----END PUBLIC KEY-----

pubkey2 Resource id #50
pubkey3 
pubkey4 
encryption false ""
encryption2 false ""

@halfer,你的加密类基本上做的就是我已经在做的事情。 - geoffreak
2个回答

2
您需要传递给此函数的关键字是 PHP 资源对象,而不是关键字本身的字符串表示形式。
$pubkey = openssl_get_publickey(base64_decode($row['public_key']));
$success = openssl_public_encrypt($data, $encrypted, $pubkey);

遗憾的是,这似乎没有任何区别。请查看我的编辑。 - geoffreak

1
因此,问题实际上与数据相关。PHP的PKI具有非常小的长度限制,无法用于加密大量数据。相反,您应该使用PKI加密对称密钥,然后使用该密钥来加密/解密数据。
如何在PHP中加密长字符串?中了解更多信息。

1
这不是一个“PHP的PKI”问题,而是RSA问题。RSA使用PKCS1填充,只能让你做出与模数长度(以字节为单位)相同减11的数字。我也回复了另一个主题。 - neubert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接