无法在PHP中创建OpenSSL S / MIME证书

时间:2015-02-12 19:09:26

标签: php ssl

我可以在命令行上创建S / MIME证书就好了:

openssl genrsa -out some_cert.key 4096
openssl req -new -key some_cert.key -out some_cert.csr

然后由我自己的权威签署证书:

openssl x509 -req -in some_cert.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out some_cert.crt

随后将其作为“人物”导入Thunderbird。证书。

但是 - 在同一台Linux机器上(即相同的OpenSSL cnf) - 我不能在PHP中这样做:

$directory = "/tmp";
$path = "/path/to/authority";
$ca = file_get_contents($path . '/ca.crt');
$cakey = array(file_get_contents($path . '/ca.key'), "authorityKeyPass");
$dn = array(
    "countryName" => "UK",
    "stateOrProvinceName" => "Scotland",
    "localityName" => "Aberdeen",
    "organizationName" => "Someorg",
    "organizationalUnitName" => "Someunit",
    "commonName" => foo@domain.org,
    "emailAddress" => foo@domain.org
);
$config = array(
    "private_key_bits" => 4096,
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
    'x509_extensions' => 'v3_ca',
);

// Generate a new private key
$privkey = openssl_pkey_new($config);

// Generate a certificate signing request
$csr = openssl_csr_new($dn, $privkey);

// Sign certificate
$sscert = openssl_csr_sign($csr, $ca, $cakey, 365);

// Export CRT (public key)
openssl_x509_export($sscert, $certout);

// Save to file
file_put_contents('/tmp/serverCASigned.crt', $certout);

文件已正确保存,但我无法将其作为“人物”导入Thunderbird。证书:没有错误消息,只是导入对话框已关闭且证书未导入。

命令行生成的.crt文件的大小与php中生成的文件大小不同...

1 个答案:

答案 0 :(得分:1)

确实是签约部分。

我找到的最佳解决方案是使用phpseclib

// Load the library phpseclib
set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib');
include_once('File/X509.php');
include_once('Crypt/RSA.php');

// CA Private key
$CAPrivKey = new Crypt_RSA();
$CAPrivKey->setPassword("authorityKeyPass");
$CAPrivKey->loadKey(file_get_contents($path . "/ca.key"));

// CA Authority
$issuer = new File_X509();
$issuer->setPrivateKey($CAPrivKey);
$issuer->loadX509(file_get_contents($path . "/ca.crt"));

// Subject - who will be signed by authority
$subject = new File_X509();
$subject->loadCSR($csrout);

// And sign it
$x509 = new File_X509();
$x509->setStartDate('-1 month');
$x509->setEndDate('+5 year');
$x509->setSerialNumber(mt_rand(1, 2147483647) . mt_rand(1, 2147483647));
$result = $x509->sign($issuer, $subject);

// Save to file
file_put_contents('/tmp/serverCASigned.crt', $x509->saveX509($result));

一切顺利......

相关问题