簡體   English   中英

PHP中的私有證書頒發機構?

[英]Private Certificate Authority in PHP?

我正在建立一個私有CA,我想使用PHP與它進行交互。 我已經嘗試使用PHP的內置openssl庫 因此,我創建了一個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處理OpenCA的私有CA?

是的,沒有。

盡管使用了提供的openssl.conf文件,PHP的OpenSSL擴展並不會自動管理證書數據庫和/或序列號,並且不提供任何實用程序來幫助您。

另一方面,數據庫本身具有相對簡單的格式 ,因此您可以使用原始文件系統功能自己實現它。 如果您確實選擇了這條路線,這里有一些提示:

  • 由於每個證書記錄都位於單獨的行上,因此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列中,但是由於您在簽名時沒有立即撤銷證書,因此不會顯示該證書-這就是為什么在到期日期和序列號之間有兩個選項卡的原因,請不要忘記在寫作時。
  • 與人們期望的相反,OpenSSL CLI工具實際上並未在同一數據庫文件上運行。 它讀取當前<filename>.old ,將其重命名為<filename>.old ,然后創建一個全新的<filename>作為<filename> 這意味着,每當您使用CLI工具時,任何文件系統所有權,授予您PHP腳本訪問權限的權限都會丟失。
    • 進行運行時檢查以訪問文件; 失敗時-中止生成/簽名並記錄/打印消息(可能帶有chownchmod指令)以通知您。
    • 串行文件和所有其他文件也相同。
  • 盡管我從未見過這種情況發生,但是密鑰生成,CSR創建和簽名中的任何一個都不是不可能的。
    • 生成的pKey,CSR,證書都是相互依賴的,並且是resource類型的(使用后應關閉)。 要拋出異常並僅在必要時關閉資源,我想預定義保存變量的變量,並在引發異常之前在處理所有有條件的無資源例程的閉包中use它們。
    • 僅在全部3個都成功之后才寫入數據庫,最后寫入串行文件。
  • 您可能已經知道了這一點,但是它們的pKey資源同時擁有私鑰和公鑰。

如您所見,如果您知道自己在做什么,它是可管理的,但是它有很多陷阱,對於簡單的PoC而言,確實不值得。 通過exec() (和兄弟姐妹)調用CLI工具是一個更簡單的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM