mTLS: openssl創建CA證書

證書可以通過openssl或者keytool創建,在本篇文章中,只介紹openssl。

openssl 生成證書

申請操作流程

  1. 生成ca證書私鑰, 文件名:ca.key
  2. 生成ca證書,文件名:ca.crt
  3. 生成Server/Client 證書私鑰,文件名:server.key, client.key
  4. 生成Server/Client 證書簽名請求,文件名:server.csr, client.csr
  5. 生成v3擴展文件(可選),文件名:v3.ext
  6. 生成Server/Client 證書,文件名:server.crt, client.crt

示意圖如下:
在這里插入圖片描述

證書簽名請求的機構信息

在生成證書簽名請求(csr)時,需要補充機構信息,如下:

參數名稱subject 簡寫參數值示例
Country NameC國家代碼比如中國就是CN
State or Province NameST省名稱Zhejiang
Locality NameL城市名稱Hangzhou
Organization NameO機構名稱
Organizational Unit NameOU機構單位名稱
Common NameCN重點參數:授權給什么,因為機構是根節點所以是授權給自己域名:www.test.com
IP:xxx.xxx.xxx.xxx
Email AddressemailAddress郵件地址

生成證書

通過下兩種方法創建證書后,最后得到有用的文件分別為:

文件
服務器端ca.crt、server.crt、(pkcs8_server.key 或 server.key)
客戶端端ca.crt、client.crt、(pkcs8_client.key 或 client.ke)

私鑰無密碼

生成ca證書私鑰, 文件名:ca.key

執行下面的命令,會輸出ca.key文件

openssl genrsa -out ca.key 2048

生成ca證書,文件名:ca.crt

使用下面命令生成ca根證書,輸出一個有效期36500天的ca.crt文件

openssl req -new -x509 -key ca.key -out ca.crt -days 36500

上面的命令需要在命令窗口中補充subject信息(注意修改-subj 中的參數),使用下面的命令直接將subject信息傳入,無需在命令窗口慢慢補充

openssl req -new -x509 -key ca.key -out ca.crt  -days 36500 -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"

注意: 如果ca.crt過期,新舊ca.crt的subject參數信息需要完全一樣,否則對那些由舊ca.crt簽名生成的證書進行校驗時會失敗報錯。

生成Server/Client 證書私鑰,文件名:server.key, client.key

生成服務器端私鑰

openssl genrsa -out server.key 2048

生成客戶端私鑰

openssl genrsa -out client.key 2048

生成Server/Client 證書簽名請求,文件名:server.csr, client.csr

生成Server證書:
生成服務器端的csr文件,為生成服務器證書做準備

openssl req -new -key server.key -out server.csr

或者添加-subj參考快速生成服務器端的csr文件(注意修改-subj 中的參數):

openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Server Company/OU=Server Unit Name/CN=ser.ts.com/emailAddress=ser@ts.com"

生成Client證書:
生成client 端csr文件,為生成client證書做準備

openssl req -new -key client.key -out client.csr

或者添加-subj參考快速生成client端的csr文件(注意修改-subj 中的參數):

openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Client Company/OU=Client Unit Name/CN=cli.ts.com/emailAddress=cli@ts.com"

生成Server/Client 證書,文件名:server.crt, client.crt

生成服務器端證書crt文件

openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt -days 36500

生成client 端證書crt文件

openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt -days 36500

將key轉換為PK8

轉換服務端key為PK8

openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt

轉換客戶端key為PK8

openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt

私鑰有密碼

生成ca的私鑰和證書, 文件名:ca.key, ca.crt

openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500

快速生成方法(注意修改-subj 中的參數):

openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500 -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"

注意:使用這種方式需要記好私鑰密碼,尤其是ca.key的密碼, 如果ca.crt過期,續期生成新的ca.crt時需要用到。

生成Server/Client 證書私鑰,文件名:server.key, client.key

生成服務端和客戶端私鑰

openssl genrsa -des3 -out server.key 1024

生成客戶端私鑰

openssl genrsa -des3 -out client.key 1024

生成Server/Client 證書簽名請求,文件名:server.csr, client.csr

根據 server.key 生成服務端的server.csr 文件

openssl req -new -key server.key -out server.csr

根據 client.key 生成客戶端的client.csr 文件

openssl req -new -key client.key -out client.csr

如果覺得上面的命令麻煩的話, 可以添加-subj參數(注意修改-subj 中的參數),快速生成。

快速生成server.csr:

openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Server Company/OU=Server Unit Name/CN=ser.ts.com/emailAddress=ser@ts.com"

快速生成client.csr

openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Client Company/OU=Client Unit Name/CN=cli.ts.com/emailAddress=cli@ts.com"

生成Server/Client 證書,文件名:server.crt, client.crt

根據 ca 證書簽名申請 server.csr 生成 服務端的x509 證書:

openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt

根據 ca 證書簽名申請 client.csr 生成客戶端的x509 證書:

openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt

#如果需要和ip綁定則加上參數。
服務端-server.crt

openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile <(printf "subjectAltName=IP:127.0.0.1")

客戶端-client.crt

openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -extfile <(printf "subjectAltName=IP:127.0.0.1")

將key轉換為不需要密碼的PK8

轉換服務端key為PK8

openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt

轉換客戶端key為PK8

openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt

完整操作命令

openssl 私鑰無密碼

mtls證書生成#生成ca證書,在目錄中輸出 ca.key 和 ca.crt 文件
openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500
openssl req -new -x509 -keyout ca.key -out ca.crt#生成 CA 私鑰
openssl genrsa -out ca.key 2048
#生成ca證書,在目錄中輸出 ca.crt 文件
openssl req -new -x509 -key ca.key -out ca.crt -days 36500
#生成ca證書,在目錄中輸出 ca.crt 文件(直接填充subject參數), -subj參數 "C=cn, ST=zj, L=hz, O=ser-ts, OU=ser-ts-un, CN=ser.ts.com, emailAddress=ser@ts.com"
openssl req -new -x509 -key ca.key -out ca.crt  -days 36500 -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"openssl req -new -x509 -key ca.key -out ca.crt  -days 36500 -sha256 -extensions v3_ca -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"#生成CA的csr文件,保存必要信息;生成CA的證書文件crt文件 
#該命令生成的ca.crt文件在mtls場景會報:io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=xxx, OU=xx, O=xx, L=hz, ST=zj, C=cn" is not a CA certificate
#以上異常產生的具體原因本人暫時未知
---
openssl req -new -key ca.key -out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
---#
#生成服務器端私鑰
openssl genrsa -out server.key 2048
#生成服務器端公鑰
openssl rsa -in server.key -pubout -out server.pem
#生成服務器端的csr文件,為生成服務器證書做準備
openssl req -new -key server.key -out server.csr
#生成服務器端的csr文件(直接填充subject參數)
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Server Company/OU=Server Unit Name/CN=ser.ts.com/emailAddress=ser@ts.com"
#生成服務器端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt -days 36500
#轉換服務端key為PK8
openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt#生成客戶端私鑰
openssl genrsa -out client.key 2048
#生成客戶端公鑰
openssl rsa -in client.key -pubout -out client.pem
#生成client 端csr文件,為生成client證書做準備
openssl req -new -key client.key -out client.csr
#生成client 端csr文件(直接填充subject參數)
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Client Company/OU=Client Unit Name/CN=cli.ts.com/emailAddress=cli@ts.com"
#生成client 端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt -days 36500
#轉換客戶端key為PK8
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt

openssl 私鑰有密碼

#生成ca證書,輸出 ca.key 和 ca.crt 文件
openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500
#生成ca證書,輸出 ca.key 和 ca.crt 文件
openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500 -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Organization Company/OU=Organizational Unit Name/CN=www.ts.com/emailAddress=m@ts.com sign CA"#生成服務端和客戶端私鑰
openssl genrsa -des3 -out server.key 1024
openssl genrsa -des3 -out client.key 1024#根據 key 生成 csr 文件
openssl req -new -key server.key -out server.csr
openssl req -new -key client.key -out client.csr
#根據 key 生成 csr 文件,快速生成csr文件
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Server Company/OU=Server Unit Name/CN=ser.ts.com/emailAddress=ser@ts.com"
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Client Company/OU=Client Unit Name/CN=cli.ts.com/emailAddress=cli@ts.com"#根據 ca 證書 server.csr 和 client.csr 生成 x509 證書
openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt
#如果需要和ip綁定則加上參數
openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile <(printf "subjectAltName=IP:127.0.0.1")
openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -extfile <(printf "subjectAltName=IP:127.0.0.1")#將 key 文件進行 PKCS#8 編碼
openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt

openssl 生成證書以及證書轉換

1.生成服務器端私鑰
openssl genrsa -out server.key 2048
2.生成服務器端公鑰
openssl rsa -in server.key -pubout -out server.pem
3.生成客戶端私鑰
openssl genrsa -out client.key 2048
4.生成客戶端公鑰
openssl rsa -in client.key -pubout -out client.pem
5.生成 CA 私鑰
openssl genrsa -out ca.key 2048
6.生成CA的csr文件,保存必要信息
openssl req -new -key ca.key -out ca.csr
7.	生成CA的證書文件crt文件
#這個命令生成ca.crt文件會在mtls場景會有信任問題,建議使用后面的命令
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
#這段命令生成的ca.crt在mtls場景可以正常使用
openssl req -new -x509 -key ca.key -out ca.crt -days 365008.生成服務器端的csr文件,為生成服務器證書做準備
openssl req -new -key server.key -out server.csr
9.生成服務器端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
10.生成client 端csr文件,為生成client證書做準備
openssl req -new -key client.key -out client.csr
11.生成client 端證書crt文件
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt12.備份服務器私鑰
openssl rsa -in server.key -out server_nopwd.key
13.生成服務器端證書
openssl x509 -req -days 365 -in server.csr -signkey server_nopwd.key -out server.crt
14.轉換服務端key為PK8
openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
15.轉換客戶端key為PK8
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt
16.轉換ca 的cert+key為pfx
openssl pkcs12 -export -in ca.crt -inkey ca.key -out ca.pfx
17.轉換ca的 pfx為jks
keytool -importkeystore -srckeystore ca.pfx -destkeystore ca.jks  -srcstoretype PKCS12 -deststoretype JKS
18. 轉換服務端 的cert+key為pfx
openssl pkcs12 -export -in server.crt -inkey server.key -out server.pfx
19. 轉換服務端的 pfx為jks
keytool -importkeystore -srckeystore server.pfx -destkeystore server.jks  -srcstoretype PKCS12 -deststoretype JKS20. 轉換客戶端 的cert+key為pfx
openssl pkcs12 -export -in client.crt -inkey client.key -out client.pfx
21. 轉換客戶端的 pfx為jks
keytool -importkeystore -srckeystore client.pfx -destkeystore client.jks  -srcstoretype PKCS12 -deststoretype JKS

SSLHandshakeException:TrustAnchor with subject “CN=xxx, OU=xx, O=xx, L=hz, ST=zj, C=cn” is not a CA certificate 解決辦法:

詳細錯誤信息:
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: sun.security.validator.ValidatorException: TrustAnchor with subject "CN=xxx, OU=xx, O=xx, L=hz, ST=zj, C=cn" is not a CA certificate
原因:
使用下面的命令生成ca.crt

openssl req -new -key ca.key -out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

解決辦法:

  1. 規避措施:
    應用程序啟動時,在啟動參數里加上如下參數,不進行校驗是否為CA
    -Djdk.security.allowNonCaAnchor=true
  2. 根本解決方法:
    在生成CA證書時明確添加是否為CA的標識 -ext BasicConstraints=ca:true
  3. 使用上面的兩種方法生成ca.crt

參考

局域網內搭建瀏覽器可信任的SSL證書
openssl創建CA證書教程
生成可信任的https證書
基于Netty的MQTT Server實現并支持SSL
記一次TrustAnchor with subject異常解決
手動實現CA數字認證(java)
java編程方式生成CA證書

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716697.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716697.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716697.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

設計模式(十三)抽象工廠模式

請直接看原文:設計模式&#xff08;十三&#xff09;抽象工廠模式_抽象工廠模式告訴我們,要針對接口而不是實現進行設計。( )-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- …

系統架構設計文檔模版

XX 系統架構設計方案 修訂記錄 日期 版本號 修訂說明 修訂人 審核人 1、概述... 5 1.1&#xff0e;業務背景... 5 1.2&#xff0e;系統總體描述... 5 1.3&#xff0e;系統邊界圖... 5 1.4&#xff0e;名詞和縮略語... 5 1.…

live555源碼學習(1)

1 基礎組件 live項目主要包含了四個基礎庫、程序入口類&#xff08;mediaServer&#xff09;和測試程序&#xff08;testProgs&#xff09;。四個基礎庫是UsageEnvironment、BasicUsageEnvironment、groupsock和liveMedia UsageEnvironment 抽象了兩個類UsageEnvironment和T…

力扣hot5---雙指針

題目&#xff1a; 解決方案&#xff1a;雙指針 指針 i 指向最左側&#xff0c;指針 j 指向最右側。此時在寬度上達到了最大值&#xff0c;那么哪個柱子更矮&#xff0c;哪個柱子向內部移動&#xff0c;知道 i 與 j 相遇。為什么呢&#xff1f; 如果哪個哪個柱子更矮&#xff0c…

代碼隨想錄算法訓練營第四十一天|198.打家劫舍,213.打家劫舍II,337.打家劫舍III

系列文章目錄 代碼隨想錄算法訓練營第一天|數組理論基礎&#xff0c;704. 二分查找&#xff0c;27. 移除元素 代碼隨想錄算法訓練營第二天|977.有序數組的平方 &#xff0c;209.長度最小的子數組 &#xff0c;59.螺旋矩陣II 代碼隨想錄算法訓練營第三天|鏈表理論基礎&#xff…

Node.js基礎---模塊化

基本概念 模塊化 模塊化是指解決一個復雜問題時&#xff0c;自上向下逐層把系統劃分成若干模塊的過程&#xff0c;對于整個系統來說&#xff0c;模塊是可組合&#xff0c;分解和更換的單元 遵守固定規則&#xff0c;把大文件拆分成獨立并互相依賴的多個小模塊 好處&#xff1a…

【計算機畢業設計】208基于SSM的在線教育網站

&#x1f64a;作者簡介&#xff1a;擁有多年開發工作經驗&#xff0c;分享技術代碼幫助學生學習&#xff0c;獨立完成自己的項目或者畢業設計。 代碼可以私聊博主獲取。&#x1f339;贈送計算機畢業設計600個選題excel文件&#xff0c;幫助大學選題。贈送開題報告模板&#xff…

OLLAMA:如何像專業人士一樣運行本地語言模型

原文 https://cheatsheet.md/llm-leaderboard/ollama.en簡介&#xff1a;揭示 OLLAMA 對本地語言模型的強大功能 您是否曾經發現自己陷入了基于云的語言模型網絡中&#xff0c;渴望獲得更本地化、更具成本效益的解決方案&#xff1f;好吧&#xff0c;您的搜索到此結束。歡迎來…

逆向案例四、進階,爬取精靈數據咨詢前五十頁數據

python代碼示例: import csv import execjs import requests f open(精靈數據.csv,w,encodingutf-8,newline) csv_writer csv.DictWriter(f,fieldnames[標題,發布時間,新聞來源,詳情頁鏈接,轉自,點擊量,新聞作者,發布時間小時,]) csv_writer.writeheader() data [] for pa…

【Ansys Fluent Web 】全新用戶界面支持訪問大規模多GPU CFD仿真

基于Web的技術將釋放云計算的強大功能&#xff0c;加速CFD仿真&#xff0c;從而減少對硬件資源的依賴。 主要亮點 ? 使用Ansys Fluent Web用戶界面?&#xff08;UI&#xff09;&#xff0c;用戶可通過任何設備與云端運行的仿真進行遠程交互 ? 該界面通過利用多GPU和云計算功…

理解python3中的回調函數

百度百科說&#xff1a;回調函數就是一個通過函數指針調用的函數。如果你把函數的指針&#xff08;地址&#xff09;作為參數傳遞給另一個函數&#xff0c;當這個指針被用來調用其所指向的函數時&#xff0c;我們就說這是回調函數。回調函數不是由該函數的實現方直接調用&#…

Sqli-labs靶場第13關詳解[Sqli-labs-less-13]

Sqli-labs-Less-13 #手工注入 post傳參了 根據題目看&#xff0c;像一個登錄頁面&#xff0c;嘗試使用布爾型盲注測試能否登錄網站 1. Username輸入a 測試是否會有報錯&#xff0c;burp抓包 報錯&#xff1a;syntax to use near a) and password() LIMIT 0,1 at line 1 分…

[python] `json.dumps()` TypeError: Object of type set is not JSON serializable

在Python中&#xff0c;當你嘗試將一個集合&#xff08;set&#xff09;類型的對象轉換為JSON格式時&#xff0c;可能會遇到“TypeError: Object of type set is not JSON serializable”的錯誤。這是因為標準的JSON格式不支持Python中的集合類型&#xff0c;JSON格式支持的數據…

【04】C語言括號匹配問題

歡迎來到土土的博客~&#x1f973;&#x1f973;&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;個人主頁&#xff1a;大耳朵土土垚的博客 &#x1f4a5; 所屬專欄&#xff1a;C語言系列函數實現 題目描述&#xff1a; 給定一個只包括 ‘(’&#xff0c;‘)’&#xf…

加密隧道技術

在現在的互聯網上傳輸數據&#xff0c;首要考慮的就是安全。這關乎到你的隱私&#xff0c;個人信息&#xff0c;財產安全等等重大問題。如果你的程序本身傳輸的信息沒有加密&#xff0c;也可以通過其他輔助方式讓你的通信加密。一些工具的就是為了解決這樣的場景的&#xff0c;…

之前續寫抖音開發者接入字節小游戲的緩存一下,現在說一下在 Windows 或者 Mac 如何用終端更換路徑?

window: 比方說你的 window 目錄下是這個路徑: 第一:E:\project\Q1\trunk\client\src,然后你想切換到下一個路徑的話,你可以這樣子操作: 第二:E:\project\Q1\trunk\client\src> cd .\usersetting 然后回車,這里不會計較大小寫 第三:你就可以在這個目錄下執行你的腳本:E:…

學習大數據,所必需的java基礎(7)

文章目錄 File類File 的靜態成員File的構造方法File的獲取方法相對路徑和絕對路徑File的創建方法File類中的刪除方法File的遍歷方法 字節流IO流介紹以及輸入輸出以及流向的介紹IO流的流向IO流分類IO流分類 OutputStream中的子類FileOutoutStream的介紹以及方法的簡單介紹InputS…

服務器中如何檢查端口是否開放

有多種方法可以檢測服務器端口是否開放。以下是一些常用的方法&#xff1a; 1. Telnet 命令&#xff1a; 使用 Telnet 命令來測試端口的可達性。在命令提示符或終端中執行以下命令&#xff1a; telnet your_server_ip your_port_number 如果連接成功&#xff0c;表示端口是…

C++ //練習 10.22 重寫統計長度小于等于6 的單詞數量的程序,使用函數代替lambda。

C Primer&#xff08;第5版&#xff09; 練習 10.22 練習 10.22 重寫統計長度小于等于6 的單詞數量的程序&#xff0c;使用函數代替lambda。 環境&#xff1a;Linux Ubuntu&#xff08;云服務器&#xff09; 工具&#xff1a;vim 代碼塊 /********************************…

PDF標準詳解(二)——PDF 對象

上一篇文章我們介紹了一個PDF文檔應該包含的最基本的結構&#xff0c;并且手寫了一個最簡單的 “Hello World” 的PDF文檔。后面我們介紹新的PDF標準給出示例時將以這個文檔為基礎&#xff0c;而不再給出完整的文檔示例&#xff0c;小伙伴想自己測試可以根據上一節的文檔來進行…