【问题标题】:Generated certificate from phpseclib is valid but not recognised by browsers after KEYGEN submit从 phpseclib 生成的证书有效但在 KEYGEN 提交后浏览器无法识别
【发布时间】:2014-11-24 08:25:10
【问题描述】:

我正在尝试创建一个简单的 PKI 基础设施供内部使用,并且我想使用 html <keygen> 标记。

我知道这个标签会向服务器发送一个 SPKAK,它必须签名。由于我不能使用exec 启动openssl,并且有php 5.5,所以处理SPKAK 的唯一方法是使用phpseclib。

这是我的代码:

<?PHP
    if(isset($_POST['key'])){
        header('Content-type: application/x-x509-user-cert');
        header('Content-disposition: attachment; filename=user.crt');
        include('File/X509.php');

        $capem = file_get_contents('root-ca.crt');

        $subject = new File_X509();
        $subject->loadCA($capem);
        $subject->loadSPKAC($_POST['key']);
        $subject->setDN('CN=Username');

        $issuer = new File_X509();
        $issuer->loadX509($capem);
        $cakey = new Crypt_RSA();
        $cakey->setPassword('SECRETPASSWORD'); 
        $cakey->loadKey(file_get_contents('root-ca.key'));
        $issuer->setPrivateKey($cakey);

        $x509 = new File_X509();
        $cert = $x509->sign($issuer, $subject);

        $x509->loadX509($cert);
        $x509->setExtension('id-ce-keyUsage', array('digitalSignature', 'keyEncipherment'));
        $x509->setStartDate('-1 day');
        $x509->setEndDate('+ 3 year');
        $x509->setSerialNumber('1235', 10);
        $cert = $x509->sign($issuer, $x509);

        echo $x509->saveX509($cert);
    }else{
?>
<form method="POST">
    <keygen name="key" keytype="RSA" challenge="ucert">
    <button>SEND</button>
</form>
<?PHP
    }
?>

奇怪的是生成的证书是有效的(windows 可以识别它)但是浏览器(我的测试中的 Chrome 和 Firefox)不识别它,给出错误 201 INVALID CERT,所以它与私钥无关存储在浏览器上。

这样做的正确方法是什么?

【问题讨论】:

  • 您是使用 X509 证书进行身份验证还是只是为特定网站建立 https 连接?如果是后者,您可能需要指定网站。例如。 $subject-&gt;setDomain('www.google.com', 'www.yahoo.com') 什么的。此外,如果您想将其用作 CA,您需要执行 $x509-&gt;makeCA();。 idk 是否回答了你的问题。
  • 我想要用于客户端身份验证的证书。我已经构建了 CA 证书,即使使用此脚本,我也可以成功创建新的有效证书。问题是 Chrome 给出了错误 201 而不是将生成的证书与其私钥相关联
  • 我的猜测是它缺少一些需要的扩展。或者可能需要一个 keyUsage 字段。当我回到家时,我可以玩这个,但如果你可以,你自己生成一个示例 X509 证书,你可以使用它登录,然后通过 pastebin.com 链接将其发布在这里,我也许可以在我在工作身份证。

标签: php phpseclib html5-keygen spkac


【解决方案1】:
<?php
include('File/X509.php');
include('Crypt/RSA.php');

// create private key / x.509 cert for stunnel / website
$privKey = new Crypt_RSA();
extract($privKey->createKey());
$privKey->loadKey($privatekey);

$pubKey = new Crypt_RSA();
$pubKey->loadKey($publickey);
$pubKey->setPublicKey();

$subject = new File_X509();
$subject->setDNProp('id-at-organizationName', 'phpseclib demo cert');
$subject->setPublicKey($pubKey);

$issuer = new File_X509();
$issuer->setPrivateKey($privKey);
$issuer->setDN($subject->getDN());

$x509 = new File_X509();

$x509->loadX509($x509->saveX509($x509->sign($issuer, $subject)));

$x509->setExtension('id-ce-keyUsage', array('digitalSignature', 'keyEncipherment', 'dataEncipherment'));
$x509->setExtension('id-ce-extKeyUsage', array('id-kp-serverAuth', 'id-kp-clientAuth'));

$result = $x509->sign($issuer, $x509);

file_put_contents('key.pem', $privKey->getPrivateKey() . "\r\n" . $x509->saveX509($result));

exec('openssl pkcs12 -export -out file.pfx -in key.pem');

我能够将生成的 file.pfx 文件导入 Google Chrome。它现在显示为“个人证书”。

【讨论】:

  • 不。私钥是由 标签生成的,所以它已经在浏览器上。我只需要签署 CSR(在 SPKAK 内),然后将其输出到浏览器。实际上这是可行的,唯一的问题是chrome不是自动导入它,而是给我错误201
  • 当我尝试通过 Google Chrome 运行您的脚本时,我收到错误 207 - 而不是错误 201。idk atm 是浏览器所期望的。我在浏览器 CA 中有签名证书,但似乎没有什么不同。谁知道 - 也许它会对你产生影响,因为你遇到了不同的错误?此外,$subject-&gt;loadCA() 无效。 loadCA() 仅用于验证证书 - 不用于创建它们。
  • 在 Firefox 中我没有收到任何错误 - 我只是被问到是否要下载文件。我在security.stackexchange.com/q/73810/15922 发布了一个尝试找出错误 207
猜你喜欢
  • 2021-11-21
  • 1970-01-01
  • 2016-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-05
相关资源
最近更新 更多