Ata*_*xia 2 php openssl cryptography rsa
以下 PEM 格式的 RSA 公钥已提供给 openssl_pkey_get_public。
-----BEGIN PUBLIC KEY-----
MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQCIZouo/rL5IkIIGrke/qkY
Nsb9JDXUw2MfutYdwIVjPiEbAcLiVxK6tOVXy7dq+hU0zyNd68bUi7VJjXWoiepS
+Mm6v76GCGvVvno48m7ofWIq6VLEaMQjIM/pzkF0TW7CmtjKvgg722Hx87AI/KCM
sWuHjhcQZsMgV4ibC8EAY6GYwHYAPWfUq+LI2wfRsQHumFC2IuT4guO/Vs5FJGXw
Arrvv7VPyKwZ8cpcZn9ka1K0N7su7QiGnzOhS3n2THaj25alE6TMXnrKmt6yIiXh
amsKVEKPPzHpw9ldTao1aG7vVNC9QXC8i9uQTWhhokxvSNw5OYFFkDZC5jD7McvB
AgMBAAE=
-----END PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
但是,方法调用失败,返回 false,并显示错误字符串error:0906D06C:PEM routines:PEM_read_bio:no start line
公钥无效吗?作为记录,我的代码从公钥模数和指数开始,并使用此处发布的算法将其转换为 PEM 格式发布的算法将其转换为 PEM 格式。
这是完整的脚本:
<?php
function createPemFromModulusAndExponent($n, $e)
{
$modulus = urlsafeB64Decode($n);
$publicExponent = urlsafeB64Decode($e);
$components = array(
'modulus' => pack('Ca*a*', 2, encodeLength(strlen($modulus)), $modulus),
'publicExponent' => pack('Ca*a*', 2, encodeLength(strlen($publicExponent)), $publicExponent)
);
$RSAPublicKey = pack('Ca*a*a*', 48, encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])), $components['modulus'], $components['publicExponent']);
$rsaOID = pack('H*', '300d06092a864886f70d0101010500');
$RSAPublicKey = chr(0) . $RSAPublicKey;
$RSAPublicKey = chr(3) . encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
$RSAPublicKey = pack('Ca*a*', 48, encodeLength(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey);
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----" . chunk_split(base64_encode($RSAPublicKey), 64) . '-----END PUBLIC KEY-----';
return $RSAPublicKey;
}
function urlsafeB64Decode($input)
{
$remainder = strlen($input) % 4;
if ($remainder)
{
$padlen = 4 - $remainder;
$input .= str_repeat('=', $padlen);
}
return base64_decode(strtr($input, '-_', '+/'));
}
function encodeLength($length)
{
if ($length <= 0x7F)
{
return chr($length);
}
$temp = ltrim(pack('N', $length), chr(0));
return pack('Ca*', 0x80 | strlen($temp), $temp);
}
$key = createPemFromModulusAndExponent('iGaLqP6y-SJCCBq5Hv6pGDbG_SQ11MNjH7rWHcCFYz4hGwHC4lcSurTlV8u3avoVNM8jXevG1Iu1SY11qInqUvjJur--hghr1b56OPJu6H1iKulSxGjEIyDP6c5BdE1uwprYyr4IO9th8fOwCPygjLFrh44XEGbDIFeImwvBAGOhmMB2AD1n1KviyNsH0bEB7phQtiLk-ILjv1bORSRl8AK677-1T8isGfHKXGZ_ZGtStDe7Lu0Ihp8zoUt59kx2o9uWpROkzF56ypresiIl4WprClRCjz8x6cPZXU2qNWhu71TQvUFwvIvbkE1oYaJMb0jcOTmBRZA2QuYw-zHLwQ', 'AQAB');
print_r($key);
print_r(openssl_pkey_get_public($key));
print_r(openssl_error_string());
Run Code Online (Sandbox Code Playgroud)
第一:旨在直接openssl_pkey_get_public加载公钥或从证书中提取公钥,如参数的文档中所述。certificateopenssl_pkey_get_public
已经针对此问题提交了一个错误,即2017 年 12 月(版本 7.1.12)的#75643,其状态为“无反馈”,目前已暂停(请注意,#75643 实际上指的是openssl_public_encrypt,但它使用与键为openssl_pkey_get_public,此处):
队列中的错误是预期的。如果您提供字符串作为 PEM(字符串不以“file://”为前缀,这将是文件路径),则首先尝试证书(使用 PEM_ASN1_read_bio)。这意味着失败并且错误被保存到队列中。然而,该队列只是已清空的 OpenSSL 的副本。之后,使用 PEM_read_bio_PUBKEY 加载密钥,这在您的情况下是成功的,因此您可以返回结果。总而言之, openssl_error_string 并不意味着操作失败,而只是发出了一些错误......
据此,该错误消息是由于未能从证书中提取密钥引起的。但是,处理会继续并直接加载密钥。换句话说,错误消息在直接加载密钥时按预期出现,并且在此上下文中可以忽略(至少在直接加载成功的情况下)。
记录如下:从 7.2(.17) 开始,显示的错误消息略有不同:error:0909006C:PEMroutines:get_name:no start line。
更新:
正如 @President James Moveon Polk 在他的评论中指出的那样,createPemFromModulusAndExponent没有正确生成密钥。如果第一个/最高有效字节大于0x7F,则模数之前必须有一个0x00字节,但目前不会发生这种情况。例如,在发布的代码中,模数以 开头(Base64url 解码)0x88,这意味着生成的(= 发布的)密钥无效。如果0x00手动添加 a 并将如此更正的值(Base64url 编码)传递给createPemFromModulusAndExponent,则以下现在有效的关键结果:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiGaLqP6y+SJCCBq5Hv6p
GDbG/SQ11MNjH7rWHcCFYz4hGwHC4lcSurTlV8u3avoVNM8jXevG1Iu1SY11qInq
UvjJur++hghr1b56OPJu6H1iKulSxGjEIyDP6c5BdE1uwprYyr4IO9th8fOwCPyg
jLFrh44XEGbDIFeImwvBAGOhmMB2AD1n1KviyNsH0bEB7phQtiLk+ILjv1bORSRl
8AK677+1T8isGfHKXGZ/ZGtStDe7Lu0Ihp8zoUt59kx2o9uWpROkzF56ypresiIl
4WprClRCjz8x6cPZXU2qNWhu71TQvUFwvIvbkE1oYaJMb0jcOTmBRZA2QuYw+zHL
wQIDAQAB
-----END PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
当然如果createPemFromModulusAndExponent能自动进行这个修正就更好了。@President James Moveon Polk 已为此提出了一个问题,在这里。
| 归档时间: |
|
| 查看次数: |
1937 次 |
| 最近记录: |