php - PHP 中的私有(private)证书颁发机构?

标签 php ssl x509 pki php-openssl

我正在设置一个私有(private) CA,我想使用 PHP 与其交互。我试过使用 PHP 的 built-in openssl library .因此,我创建了一个 CSR,并使用 openssl_csr_sign 对其进行签名。

这确实签署了 CSR,仅此而已。在 OpenSSL 的 CLI 中,它类似于

openssl x509 -req -days 360 -in file.csr -CA ca.crt -CAkey ca.key ...

而我想要类似的东西

openssl ca -cert ca.crt -keyfile ca.key -in file.csr -out file.crt ...

基本上它使用 x509 模块而不是 ca 模块对其进行签名。所以它不会将其写入openssl.cnf中指定的数据库,它不会使用或更新序列号;它更像是“我信任这个人,所以我会用我的私钥签署他的公钥”而不是实际的 CA。有没有办法在 PHP 中管理私有(private) CA,是否使用 openssl?

最佳答案

是也不是。

尽管使用提供的 openssl.conf 文件,但 PHP 的 OpenSSL 扩展不会自动管理证书数据库和/或序列号,并且它不会提供任何实用程序来帮助实现这一点。

另一方面,数据库本身有一个relatively simple format ,因此您可以使用原始文件系统函数自己实现它。如果您真的选择了这条路线,这里有一些提示:

  • 由于每个证书记录都位于单独的一行中,fgets()解析它时派上用场。
    • fscanf()乍一看看起来更好,但它对所有空格都一视同仁,制表符是格式的重要组成部分,所以 ...
    • file()更容易,但仅供阅读。您可能需要同时读取和写入,并且需要获取文件锁以避免竞争条件。
  • DN 字符串元素可以按任意顺序排列,并非所有元素都是强制性的,并且分隔符在值中出现时不会转义,因此您会发现很难以与 OpenSSL CLI 工具相同的方式生成它.你最好做一个 openssl_x509_parse()在刚刚签署的证书上并从那里读取值。
    • 我不记得它是什么,但该函数在 PHP 5 和 7 之间的结果上有一些细微差别,它对 DN 字符串很重要。
  • PHP(正确地)将序列号作为整数处理,但它以十六进制表示法存储,因此您需要来回转换它。
    • 序列文件存储下一个序列号,所以你可以做$serial = hexdec(file_get_contents($pathToSerial)) , 将该变量传递给 openssl_csr_sign()然后写sprintf("%X\n", $serial + 1)到文件。
  • 吊销时间戳位于数据库的第 3 列,但由于您在签署证书时没有立即吊销证书,因此它不会出现 - 这就是为什么在到期日期和序列号之间有 2 个选项卡的原因,不要写作时不要忘记这一点。
  • 与人们的预期相反,OpenSSL CLI 工具实际上并不对同一个数据库文件进行操作。它读取当前的,将其重命名为 <filename>.old然后创建一个全新的 <filename> .这意味着无论何时使用 CLI 工具,任何文件系统所有权和授予 PHP 脚本访问权限的权限都会丢失。
    • 对文件的访问进行运行时检查;失败时 - 中止生成/签名并记录/打印消息(可能带有 chownchmod 说明)以通知您。
    • 同样适用于序列号和所有其他文件。
  • 虽然我从未见过这种情况,但 key 生成、CSR 创建和签名中的任何一个都可能失败。
    • 生成的 pKey、CSR、证书都是相互依赖的,类型为 resource (使用后应关闭)。要抛出异常并仅在必要时关闭资源,我喜欢预先定义保存它们的变量和 use它们在一个闭包中,该闭包在抛出异常之前处理所有条件性无资源例程。
    • 3个都成功后才写入数据库,最后写入串口文件。
  • 您可能已经想通了,但是他们的 pKey 资源同时包含私钥和公钥。

如您所见,如果您知道自己在做什么,它是可以管理的,但它有很多问题,对于简单的 PoC 来说并不值得。通过 exec() 调用 CLI 工具(和 sibling )是一个更简单的选择。

关于php - PHP 中的私有(private)证书颁发机构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48164595/

相关文章:

ruby - 使用 heroku OSX 终端命令时中止 ruby​​ 陷阱段错误

PHP 代码气味检测器

php - DOCUMENT_ROOT 上方目录的 PHP $_SERVER 变量是什么?

apache - 谷歌云平台计算引擎 SSL 证书

ssl - SSL使用.net mq客户端SSLV3连接到MQ?

c# - 是否可以仅使用 C# 以编程方式生成 X509 证书?

security - "an introduction to openssl programming."文章。过期证书

php - 如何从同一个表中的单个 MySQL 查询中获取两组结果?

php - 哪个联接适合我在 CI 中的 Ajax 数据表