1

我正在尝试创建一个简单的 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,因此它与存储在浏览器上的私钥无关.

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

4

1 回答 1

0
<?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。它现在显示为“个人证书”。

于 2014-11-27T01:39:30.690 回答