openssl_verify和“错误:0906D06C:PEM例程:PEM_read_bio:无起始行”

时间:2010-08-30 05:20:43

标签: php ssl openssl

我正在尝试在PHP中使用OpenSSL函数进行RSA签名/验证。 当我尝试使用我的公钥openssl_verify时,我收到此错误: error:0906D06C:PEM routines:PEM_read_bio:no start line ,但函数本身正常工作(返回0)如果消息被修改,如果消息被修改则为1)。 openssl_sign工作正常。

我该如何解决?

目前,我使用openssl生成的公钥:

define("SC_MSG_PUBLIC", <<<EOD
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALjPcOckMHDVLiUstcRwwx8kF5PzsiEs
rskyndWisbXMLU9BHomXwL7Qg2L91jE+sNSobkzBDF41CbwDiNlofZUCAwEAAQ==
-----END PUBLIC KEY-----
EOD
);

任何有关此错误触发的想法,但一切正常?

尝试从私有中生成公钥,并使用它,但它看起来完全相同,同样的错误消息:-S

$pkey = openssl_pkey_get_private(SC_MSG_PRIVATE);
$keyDetails = openssl_pkey_get_details($pkey);
file_put_contents('c:\publickey', $keyDetails['key']);

另外,我试图安装所有版本的新版本(PHP 5.3.1,OpenSSL 1.0.0a) - 结果相同。而且,我在窗户上。

4 个答案:

答案 0 :(得分:15)

您是否尝试使用包含公钥而非纯公钥的(可能是自签名的)证书来调用 openssl_verify()

据我所知,有些PHP OpenSSL函数不能正确支持裸公钥,尽管看起来很奇怪它确实可以正确验证。

<?php
$private = openssl_pkey_get_private(file_get_contents('private'), 'passphrase');

// This causes the "no start line" error when using a naked public key:
$public  = openssl_pkey_get_public(file_get_contents('public')); // <-- this should be cert

echo openssl_error_string()."\n";

openssl_sign('Test', $sig, $private);
var_dump(openssl_verify('Test', $sig, $public));

echo openssl_error_string()."\n";
?>

将公钥转换为Linux / UNIX shell(如bash)中的简单证书的示例(有关更多信息,请参阅OpenSSL文档或一些教程):

# Create certificate request
openssl req -new -days 3600 -key [PRIVATE-KEY-FILE] -out [REQUEST-TMP-FILE]

# Create certificate from request
RANDFILE=[RANDOM-TMP-FILE] openssl x509 -req -in [REQUEST-TMP-FILE] -signkey [PRIVATE-KEY-FILE] -out [CERTIFICATE-OUT-FILE]

这也会创建您之后可能要删除的临时文件,即 [REQUEST-TMP-FILE] [RANDOM-TMP-FILE]

可以在http://de.php.net/manual/en/function.openssl-csr-new.php找到PHP示例代码。

答案 1 :(得分:3)

如果其他所有人都有成功操作自动重置为零的errno,OpenSSL会出现“错误堆栈”,需要手动清空。根据{{​​3}},查看openssl_error_string函数implemented。您可能看到的错误消息与您的代码无关;尝试在代码之前添加:

while ($msg = openssl_error_string()) {};

并在每一行之间:

while ($msg = openssl_error_string())
    echo "OpenSSL error when doing foo:" . $msg . "<br />\n";

答案 2 :(得分:2)

您可以更轻松地使用phpseclib进行签名创建/验证:

http://phpseclib.sourceforge.net/documentation/misc_crypt.html#misc_crypt_rsa_examples

答案 3 :(得分:1)

原因:

此错误通常是由.crt文件开头的一个损坏字符引起的。因此,您可能在SSL证书文件(.crt)或SSL密钥文件(.key)中有额外的空格,额外的字符,额外的行等。

可能的解决方案:

  1. 检查.crt文件。
  2. 字符问题可能在您的密钥中,尝试此操作(没有换行符等):
  3. define("SC_MSG_PUBLIC", "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALjPcOckMHDVLiUstcRwwx8kF5PzsiEsrskyndWisbXMLU9BHomXwL7Qg2L91jE+sNSobkzBDF41CbwDiNlofZUCAwEAAQ==");