资讯详情 仓颉编程语言 stdx.crypto.x509 结构体全解析:DerBlob、Pem 编解码与证书验证配置实战
📅 2026/10/15 3:46:46
文档知识库教程OpenHarmony【免费下载链接】CangjieCorpus本仓库为仓颉编程语言语料库聚焦 仓颉编程语言 核心知识体系整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源经结构化处理与专业标注构建为支持 RAG检索增强生成技术 的高质量知识基座适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用推动鸿蒙开发生态智能化升级项目地址https://gitcode.com/Cangjie/CangjieCorpus点击查看免费下载stdx.crypto.x509是仓颉标准库扩展中负责数字证书处理的核心包覆盖 X.509 证书的解析、序列化、验证、自签名证书创建以及证书链构建等能力。本文以 x509_package_structs.md 中定义的 10 个核心结构体为线索系统讲解二进制证书流DerBlob、PEM 文本编解码Pem/PemEntry、证书序列号与签名、密钥用法约束、验证选项VerifyOption以及证书/证书请求信息结构体的字段语义、默认值与构造规则并结合仓库中的包总览与示例代码给出可直接落地的仓颉编码实践。读完本文你将能够熟练运用这些结构体完成证书数据的读取、解析、编码、创建与验证配置。x509 包全景结构体在证书处理链路中的角色在进入结构体细节之前先厘清它们在 x509 包中的位置。根据 x509_package_overview.md该包对外提供的能力包括解析和序列化 X509 证书、验证证书、创建自签名证书、创建和验证证书链等整体 API 由类型别名、接口、类、枚举、结构体与异常类组成接口DHParameters、Key、PrivateKey、PublicKey提供密钥的 DER/PEM 编解码与使用入口类X509CertificateX.509 数字证书、X509CertificateRequest证书签名请求、X509Name证书实体可辨识名称枚举PublicKeyAlgorithmRSA、DSA、ECDSA、SignatureAlgorithm12 种签名算法结构体本文主角包括DerBlob、ExtKeyUsage、KeyUsage、Pem、PemEntry、SerialNumber、Signature、VerifyOption、X509CertificateInfo、X509CertificateRequestInfo异常类X509Exception全部结构体在非法输入场景下统一抛出该异常。从数据流角度看这些结构体恰好构成两条典型链路解析链路读取 PEM/DER 数据 →Pem/PemEntry/DerBlob→X509Certificate/X509CertificateRequest/PublicKey/PrivateKey与构造链路SerialNumber/KeyUsage/ExtKeyUsage→X509CertificateInfo/X509CertificateRequestInfo→ 证书/CSR 对象。下面的小节将逐一展开。需要特别注意的是x509 包依赖 OpenSSL 3 的 crypto 动态库。Linux 上需确保系统含有libcrypto.so与libcrypto.so.3如 Ubuntu 22.04 可sudo apt install libssl-devWindows 需要libcrypto.dll.a或libcrypto.lib与libcrypto-3-x64.dllmacOS 使用brew install openssl3并确保含有libcrypto.dylib与libcrypto.3.dylib。若未安装或版本过低程序运行时可能抛出X509Exception: Can not load openssl library or function xxx。该限制直接影响所有结构体背后基于 OpenSSL 的实现行为。DerBlob承载 DER 二进制证书流的基础载体DerBlob是 x509 包中最基础的二进制数据载体Crypto 支持配置二进制证书流。DERDistinguished Encoding Rules是 X.509 证书的二进制编码规则用户在读取二进制证书数据后创建DerBlob对象即可将其解析成X509Certificate、X509CertificateRequest、PublicKey、PrivateKey等对象。public struct DerBlob : EquatableDerBlob Hashable { public init(content: ArrayByte) }该结构体同时实现EquatableDerBlob与Hashable因此可以直接参与判等与哈希运算例如放入HashSet或作为HashMap的键。prop body 与 prop sizebody属性返回DerBlob对象中的字符序列类型为ArrayBytesize属性返回字符序列的大小类型为Int64。二者配合可用于访问或统计证书二进制内容的原始字节。public prop body: ArrayByte public prop size: Int64init(Array )从字节序列构造public init(content: ArrayByte)参数content为二进制字符序列。典型来源是从文件读取的字节流例如import stdx.crypto.x509.* import std.fs.File // 读取 DER 证书文件字节构造 DerBlob let bytes File.readFrom(./server.der) let blob DerBlob(content: bytes) let cert X509Certificate.decodeFromDer(blob)哈希与判等DerBlob提供hashCode(): Int64对对象进行哈希计算重载运算符(other: DerBlob): Bool与!(other: DerBlob): Bool用于判定两个二进制证书流是否相同。对象相同返回true不同返回false。Pem 与 PemEntryPEM 文本格式的结构化编解码PEM 文本格式经常用于存储证书和密钥其编码结构包含三部分第一行是由-----BEGIN、标签与-----组成的 UTF-8 字符串中间是正文即实际二进制内容经 base64 编码得到的可打印字符串详细规范可参考 RFC 7468最后一行是由-----END、标签与-----组成的 UTF-8 字符串详见 RFC 1421。在旧版 PEM 编码标准中第一行与正文之间还包含条目头headers。为覆盖不同的使用场景x509 包提供了PemEntry单个 PEM 基础结构与Pem条目序列两个结构体。struct PemPEM 条目序列public struct Pem : CollectionPemEntry ToString { public Pem(private let items: ArrayPemEntry) }Pem实现CollectionPemEntry与ToString本质是多个PemEntry的序列容器可容纳证书链中多张证书或密钥集合。核心成员prop size: Int64条目序列的数量重写自Collection构造方法Pem(items: ArrayPemEntry)以多个PemEntry对象构造Pemstatic func decode(text: String): Pem将 PEM 文本解码为条目序列。参数text为 PEM 字符串当数据为空或解码失败时抛出X509Exceptionfunc encode(): String返回 PEM 格式的字符串行结束符根据当前操作系统生成Windows 与 Unix 平台的行尾处理不同跨平台场景需留意override func isEmpty(): Bool判断 PEM 文本解码后条目序列是否为空override func iterator(): IteratorPemEntry生成条目序列的迭代器配合for..in遍历override func toString(): String返回包含每个条目序列标签的字符串。典型解析场景一个 PEM 文件可能包含证书链多张证书依次排列Pem.decode可一次性得到全部条目import stdx.crypto.x509.* let pemText -----BEGIN CERTIFICATE----- ...base64 内容... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ...base64 内容... -----END CERTIFICATE----- let pem Pem.decode(pemText) println(链中包含的条目数: ${pem.size}) for (entry in pem) { println(entry.label) // 每条记录的标签如 CERTIFICATE }struct PemEntry单个 PEM 条目public struct PemEntry : ToString { public static let LABEL_CERTIFICATE CERTIFICATE public static let LABEL_X509_CRL X509 CRL public static let LABEL_CERTIFICATE_REQUEST CERTIFICATE REQUEST public static let LABEL_PRIVATE_KEY PRIVATE KEY public static let LABEL_EC_PRIVATE_KEY EC PRIVATE KEY public static let LABEL_ENCRYPTED_PRIVATE_KEY ENCRYPTED PRIVATE KEY public static let LABEL_RSA_PRIVATE_KEY RSA PRIVATE KEY public static let LABEL_SM2_PRIVATE_KEY SM2 PRIVATE KEY public static let LABEL_PUBLIC_KEY PUBLIC KEY public static let LABEL_EC_PARAMETERS EC PARAMETERS public static let LABEL_DH_PARAMETERS DH PARAMETERS public PemEntry( public let label: String, public let headers: Array(String, String), public let body: ?DerBlob ) public init(label: String, body: DerBlob) }PemEntry用于存储单个 PEM 基础结构实现ToString。其中label标签、headers条目头键值对数组、body二进制内容可为空三个字段均为public let只读成员。11 个静态标签常量用于标识条目类型语义如下静态常量取值条目类型LABEL_CERTIFICATECERTIFICATE证书LABEL_X509_CRLX509 CRL证书吊销列表LABEL_CERTIFICATE_REQUESTCERTIFICATE REQUEST证书签名请求LABEL_PRIVATE_KEYPRIVATE KEYPKCS #8 标准未加密的私钥LABEL_EC_PRIVATE_KEYEC PRIVATE KEY椭圆曲线私钥LABEL_ENCRYPTED_PRIVATE_KEYENCRYPTED PRIVATE KEYPKCS #8 标准加密的私钥LABEL_RSA_PRIVATE_KEYRSA PRIVATE KEYRSA 私钥LABEL_SM2_PRIVATE_KEYSM2 PRIVATE KEYSM2 私钥LABEL_PUBLIC_KEYPUBLIC KEY公钥LABEL_EC_PARAMETERSEC PARAMETERS椭圆曲线参数LABEL_DH_PARAMETERSDH PARAMETERSDH 密钥参数构造方式有两种// 完整构造包含标签、条目头与二进制内容 public PemEntry(label: String, headers: Array(String, String), body: ?DerBlob) // 简化构造仅标签与二进制内容headers 为空 public init(label: String, body: DerBlob)核心方法func encode(): String返回 PEM 格式字符串行结束符根据当前操作系统生成func header(name: String): IteratorString通过条目头名称找到对应条目内容返回内容迭代器旧版 PEM 标准中可能存在的条目头场景override func toString(): String返回 PEM 对象的标签和二进制内容长度。实践示例——将证书编码为 PEM 条目并还原import stdx.crypto.x509.* // 证书对象编码为 PEM 条目 let entry: PemEntry cert.encodeToPem() println(标签: ${entry.label}) println(条目内容: ${entry.encode()}) // 依据标签判断类型 if (entry.label PemEntry.LABEL_CERTIFICATE) { println(这是一张证书) }与类/接口的衔接PemEntry是各类编解码方法的标准返回类型X509Certificate.encodeToPem()、X509CertificateRequest.encodeToPem()、PublicKey.encodeToPem()、PrivateKey.encodeToPem()均返回PemEntry详见 x509_package_classes.md 与 x509_package_interfaces.md。其中PrivateKey.encodeToPem(password!: ?String)支持传入密码对私钥进行加密编码密码为None时不加密密码为空字符串或加密失败时抛出X509Exception。SerialNumber证书唯一序列号的生成与比较SerialNumber为数字证书的序列号是数字证书中的唯一标识符。根据 RFC 5280 规范证书序列号的长度不应超过 20 字节。public struct SerialNumber : EquatableSerialNumber Hashable ToString { public init(length!: UInt8 16) }该结构体同时实现Equatable、Hashable与ToString。构造规则init(length!: UInt8 16)用于生成指定长度的随机序列号单位为字节默认值为 16即默认 128 比特与X509CertificateInfo默认序列号长度一致。当length等于 0 或大于 20 时抛出X509Exception。成员能力hashCode(): Int64返回证书序列号哈希值toString(): String生成证书序列号字符串格式为十六进制(other: SerialNumber)/!(other: SerialNumber)序列号判等/判不等返回Bool。实践示例来自 sample_x509.md 的证书创建场景import stdx.crypto.x509.* // 生成长度为 20 字节的随机序列号规范允许的最大长度 let serialNumber SerialNumber(length: 20) println(serialNumber) // 十六进制字符串Signature证书签名的二进制表示Signature结构体表示数字证书的签名用来验证身份的正确性。public struct Signature : EquatableSignature Hashable { }核心成员prop signatureValue: DerBlob返回证书签名的二进制DER 编码的签名值hashCode(): Int64返回证书签名哈希值(other: Signature)/!(other: Signature)证书签名判等/判不等。在证书解析时X509Certificate.signature与X509CertificateRequest.signature属性即返回该结构体与之配套的签名算法通过SignatureAlgorithm枚举描述如SHA256WithRSA、ECDSAWithSHA256等 12 种详见 x509_package_enums.md。实际签名算法则由证书扩展字段与密钥类型共同决定。KeyUsage 与 ExtKeyUsage密钥用途与扩展密钥用途约束数字证书的扩展字段中通常会携带公钥的用法说明与扩展密钥用法说明用于限制证书私钥/公钥的使用范围是 PKI 安全策略的重要组成部分。struct KeyUsage公钥用法按位标志public struct KeyUsage : ToString { public static let DigitalSignature: UInt16 0x0080 public static let NonRepudiation: UInt16 0x0040 public static let KeyEncipherment: UInt16 0x0020 public static let DataEncipherment: UInt16 0x0010 public static let KeyAgreement: UInt16 0x0008 public static let CertSign: UInt16 0x0004 public static let CRLSign: UInt16 0x0002 public static let EncipherOnly: UInt16 0x0001 public static let DecipherOnly: UInt16 0x0100 public init(keys: UInt16) }KeyUsage目前支持的用途有DigitalSignature、NonRepudiation、KeyEncipherment、DataEncipherment、KeyAgreement、CertSign、CRLSign、EncipherOnly、DecipherOnly。各标志位的语义如下静态常量值语义DigitalSignature0x0080私钥可用于除签发证书、签发 CRL 和非否认性服务之外的各种数字签名操作公钥用于验证这些签名NonRepudiation0x0040私钥可用于非否认性服务中的签名公钥用于验证签名KeyEncipherment0x0020密钥用于加密传输其他密钥DataEncipherment0x0010公钥用于直接加密数据KeyAgreement0x0008密钥用于密钥协商CertSign0x0004私钥用于证书签名公钥用于验证证书签名专用于 CA 证书CRLSign0x0002私钥用于对 CRL 签名公钥用于验证 CRL 签名EncipherOnly0x0001证书公钥在密钥协商中仅用于加密计算配合KeyAgreement使用才有意义DecipherOnly0x0100证书公钥在密钥协商中仅用于解密计算配合KeyAgreement使用才有意义构造方式init(keys: UInt16)构造指定用途的密钥用法。同一密钥可以有多种用途官方文档明确建议使用本结构中提供的密钥用法变量通过按位或的方式传入参数import stdx.crypto.x509.* // 同时声明数字签名与密钥加密传输两种用途 let usage KeyUsage(keys: KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment) // 生成密钥用途字符串 println(usage.toString())struct ExtKeyUsage扩展密钥用法用途编号public struct ExtKeyUsage : ToString { public static let AnyKey: UInt16 0 public static let ServerAuth: UInt16 1 public static let ClientAuth: UInt16 2 public static let EmailProtection: UInt16 3 public static let CodeSigning: UInt16 4 public static let OCSPSigning: UInt16 5 public static let TimeStamping: UInt16 6 public init(keys: ArrayUInt16) }ExtKeyUsage目前支持的用途有ServerAuth、ClientAuth、EmailProtection、CodeSigning、OCSPSigning、TimeStamping。各用途编号语义如下静态常量值语义AnyKey0应用于任意用途ServerAuth1用于 SSL 的服务端验证ClientAuth2用于 SSL 的客户端验证EmailProtection3用于电子邮件的加解密、签名等CodeSigning4用于代码签名OCSPSigning5用于对 OCSP 响应包进行签名TimeStamping6用于将对象摘要值与时间绑定构造方式init(keys: ArrayUInt16)构造指定用途的扩展密钥用法与KeyUsage相同同一个密钥可以有多种用途通过传入用途编号数组实现import stdx.crypto.x509.* // 服务端证书同时声明服务端验证与客户端验证用途 let extUsage ExtKeyUsage(keys: [ExtKeyUsage.ServerAuth, ExtKeyUsage.ClientAuth]) println(extUsage.toString())VerifyOption证书验证的配置中心VerifyOption用于为 x509 证书验证函数X509Certificate.verify(verifyOption)提供配置选项。public struct VerifyOption { public var time: DateTime DateTime.now() public var dnsName: String public var roots: ArrayX509Certificate X509Certificate.systemRootCerts() public var intermediates: ArrayX509Certificate ArrayX509Certificate() }四个可写字段public var及其默认值如下字段类型默认值语义timeDateTimeDateTime.now()校验时间默认为创建选项的时间用于有效期判断dnsNameString校验域名默认为空只有设置域名时才会进行该处校验rootsArrayX509CertificateX509Certificate.systemRootCerts()根证书链默认取系统根证书链intermediatesArrayX509Certificate空数组中间证书链默认为空X509Certificate.systemRootCerts()静态方法返回操作系统的根证书支持 Linux、macOS 和 Windows 平台见 x509_package_classes.md。根据X509Certificate.verify的文档验证优先级依次为优先验证有效期依据time字段可选验证 DNS 域名仅当dnsName非空时执行将证书备选名称中的 DNS 域名与目标域名比对最后根据根证书和中间证书验证其有效性构建信任链。验证成功返回true失败返回false检验过程中若发生内部错误如内存分配异常则抛出X509Exception。实战示例——sample_x509.md 中的验证场景完整展示了三个维度的组合用法import std.fs.File import stdx.crypto.x509.* import std.time.DateTime // 按时间与信任链验证 func testVerifyByTime(cert: X509Certificate, roots: ArrayX509Certificate, middles: ArrayX509Certificate) { var opt VerifyOption() opt.roots roots opt.intermediates middles println(Verify result: ${cert.verify(opt)}) // 指定校验时间回拨到过去某时刻 opt.time DateTime.of(year: 2023, month: 7, dayOfMonth: 1) println(Verify result: ${cert.verify(opt)}) } // 按 DNS 域名验证 func testVerifyByDNS(cert: X509Certificate) { var opt VerifyOption() opt.dnsName www.example.com println(cert DNS names: ${cert.dnsNames}) println(Verify result: ${cert.verify(opt)}) }证书链关系示例来自官方示例注释演示了根证书、中间证书与服务端证书的拓扑* root[0] root[1] * / \ | * mid[0] mid[1] mid[2] * | | * server[0] server[1]对应的验证结论cert.verify(opt)返回Boolcert0仅凭root[0]验证为false补上mid[0]后为truecert1凭root[1]加mid[2]验证为true。这直观说明仅提供根证书而缺少中间证书时信任链无法闭合。X509CertificateInfo 与 X509CertificateRequestInfo证书/请求的信息蓝图这两个结构体分别承载创建证书与证书签名请求所需的全部信息字段是构造链路的输入核心。struct X509CertificateInfo证书信息public struct X509CertificateInfo { public var serialNumber: SerialNumber public var notBefore: DateTime public var notAfter: DateTime public var subject: ?X509Name public var dnsNames: ArrayString public var emailAddresses: ArrayString public var IPAddresses: ArrayIP public var keyUsage: ?KeyUsage public var extKeyUsage: ?ExtKeyUsage public init( serialNumber!: ?SerialNumber None, notBefore!: ?DateTime None, notAfter!: ?DateTime None, subject!: ?X509Name None, dnsNames!: ArrayString ArrayString(), emailAddresses!: ArrayString ArrayString(), IPAddresses!: ArrayIP ArrayIP(), keyUsage!: ?KeyUsage None, extKeyUsage!: ?ExtKeyUsage None ) }X509CertificateInfo结构包含证书的序列号、有效期、实体可辨识名称、域名、email 地址、IP 地址、密钥用法和扩展密钥用法。其IP类型是 x509_package_type.md 中定义的别名public type IP ArrayByte即用字节数组记录 IPv4/IPv6 地址IPv4 为 4 字节IPv6 为 16 字节。全部 9 个字段与构造默认值字段类型构造默认值语义serialNumberSerialNumberNone数字证书序列号使用默认值时序列号长度为 128 比特16 字节notBeforeDateTimeNone有效期开始时间默认值为X509CertificateInfo创建的时间notAfterDateTimeNone有效期截止时间默认值为notBefore往后 1 年的时间subject?X509NameNone数字证书使用者信息dnsNamesArrayString空字符串数组域名列表需要用户保证输入域名的有效性emailAddressesArrayString空字符串数组email 地址列表需要用户保证输入 email 的有效性IPAddressesArrayIP空 IP 数组IP 地址列表keyUsage?KeyUsageNone密钥用法extKeyUsage?ExtKeyUsageNone扩展密钥用法异常规则当IPAddresses列表中包含无效的 IP 地址时构造抛出X509Exception。实践示例——创建证书时的信息配置来自 sample_x509.mdimport stdx.crypto.x509.* import std.time.DateTime let x509Name X509Name( countryName: CN, provinceName: beijing, localityName: haidian, organizationName: organization, organizationalUnitName: organization unit, commonName: x509, email: testemail.com ) let serialNumber SerialNumber(length: 20) let startTime: DateTime DateTime.now() let endTime: DateTime startTime.addYears(1) let ip1: IP [8, 8, 8, 8] // IPv4 let ip2: IP [0, 1, 0, 1, 0, 1, 0, 1, 0, 8, 0, 8, 0, 8, 0, 8] // IPv6 let certInfo X509CertificateInfo( serialNumber: serialNumber, notBefore: startTime, notAfter: endTime, subject: x509Name, dnsNames: [b.com], IPAddresses: [ip1, ip2] )随后可用该certInfo配合父证书与公私钥创建X509Certificatelet cert X509Certificate(certInfo, parent: parentCert, publicKey: usrPublicKey, privateKey: parentPrivateKey)需要说明的是X509Certificate构造要求publicKey仅支持 RSA、ECDSA 和 DSA 公钥privateKey仅支持对应私钥当公钥/私钥类型不支持、私钥类型与签名算法不匹配或证书信息设置失败时抛出X509Exception。签名算法默认值为None此时默认摘要类型为 SHA256对应 digest 包中的 SHA256。struct X509CertificateRequestInfo证书签名请求信息public struct X509CertificateRequestInfo { public var subject: ?X509Name public var dnsNames: ArrayString public var emailAddresses: ArrayString public var IPAddresses: ArrayIP public init( subject!: ?X509Name None, dnsNames!: ArrayString ArrayString(), emailAddresses!: ArrayString ArrayString(), IPAddresses!: ArrayIP ArrayIP() ) }X509CertificateRequestInfo结构包含证书请求的实体可辨识名称、域名、email 地址和 IP 地址。与X509CertificateInfo相比它不包含序列号、有效期与密钥用法字段——证书签名请求CSR只提交身份信息序列号、有效期和用途由 CA 在签发时决定。字段与构造默认值字段类型构造默认值语义subject?X509NameNone数字证书的使用者信息dnsNamesArrayString空字符串数组域名列表需用户保证输入域名的有效性emailAddressesArrayString空字符串数组email 地址列表需用户保证输入 email 的有效性IPAddressesArrayIP空 IP 数组IP 地址列表异常规则与X509CertificateInfo一致IPAddresses中包含无效 IP 地址时抛出X509Exception。实践示例——创建证书签名请求来自 sample_x509.mdimport stdx.crypto.x509.* import std.fs.* import std.io.* let rsaPem String.fromUtf8(readToEnd(File(./rsa_private_key.pem, Read))) let rsa PrivateKey.decodeFromPem(rsaPem) let csrInfo X509CertificateRequestInfo( subject: x509Name, dnsNames: [b.com], IPAddresses: [ip1, ip2] ) let csr X509CertificateRequest(rsa, certificateRequestInfo: csrInfo, signatureAlgorithm: SHA256WithRSA) println(Subject: ${csr.subject.toString()}) println(IPAddresses: ${csr.IPAddresses}) println(dnsNames: ${csr.dnsNames})结构体间的关系与典型调用链将上述结构体串起来可以得到 x509 包中的两条完整调用链解析链路读取证书/密钥数据读取文件得到字符串/字节流文本场景Pem.decode(text)得到Pem条目序列或直接调用X509Certificate.decodeFromPem(pem)得到ArrayX509Certificate二进制场景DerBlob(content: bytes)后调用X509Certificate.decodeFromDer(blob)通过证书对象的serialNumberSerialNumber、signatureSignature、keyUsageKeyUsage、extKeyUsageExtKeyUsage、dnsNames/emailAddresses/IPAddresses等属性读取解析结果验证时构造VerifyOption配置time/dnsName/roots/intermediates后调用cert.verify(opt)。构造链路创建证书/CSR生成SerialNumber(length: 20)、构造X509Name与KeyUsage/ExtKeyUsage组装X509CertificateInfo证书或X509CertificateRequestInfoCSR调用X509Certificate(certInfo, parent: …, publicKey: …, privateKey: …)或X509CertificateRequest(privateKey, certificateRequestInfo: …, signatureAlgorithm: …)用encodeToPem()返回PemEntry或encodeToDer()返回DerBlob导出结果。常见异常与注意事项汇总所有结构体在输入非法时统一抛出 X509Exception该异常类继承自Exception支持无参构造与init(message: String)两种方式。使用中需要特别留意以下异常触发点场景触发条件SerialNumber(length)length等于 0 或大于 20超出 RFC 5280 规范Pem.decode(text)数据为空或解码失败X509CertificateInfo/X509CertificateRequestInfo构造IPAddresses中包含无效 IP 地址X509Certificate构造公钥/私钥类型不支持、私钥类型与签名算法不匹配、证书信息设置失败X509CertificateRequest构造私钥类型不支持、私钥类型与签名算法不匹配、证书签名信息设置失败PrivateKey.decodeFromPem(text, password)等解密解码失败或password为空字符串OpenSSL 环境缺失未安装 OpenSSL 3 或版本过低运行时报Can not load openssl library or function xxx此外dnsNames与emailAddresses的有效性由调用方保证API 不校验域名与邮箱格式证书序列号默认 128 比特、有效期默认notBefore起 1 年等默认行为在依赖默认参数构造时应了然于心。掌握上述结构体与默认值语义即可在仓颉工程中熟练完成证书数据的读取、解析、创建与验证配置。赞分享文档知识库教程OpenHarmony【免费下载链接】CangjieCorpus本仓库为仓颉编程语言语料库聚焦 仓颉编程语言 核心知识体系整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源经结构化处理与专业标注构建为支持 RAG检索增强生成技术 的高质量知识基座适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用推动鸿蒙开发生态智能化升级项目地址https://gitcode.com/Cangjie/CangjieCorpus点击查看免费下载相关推荐仓颉 stdx.crypto.common 结构体深度解析DerBlob、Pem 与 PemEntry 的二进制证书流与 PEM 编解码实战仓颉 stdx.crypto.common 结构体深度解析DerBlob、Pem 与 PemEntry 的二进制证书流与 PEM 编解码实战 stdx.cry标准库网络密码学并发编程仓颉 stdx 加密基础结构体完全指南DerBlob、Pem 与 PemEntry 的解析、编码与实战应用仓颉 stdx 加密基础结构体完全指南DerBlob、Pem 与 PemEntry 的解析、编码与实战应用 stdx.crypto.common 包是仓颉C标准库网络密码学并发编程仓颉 stdx.crypto.x509 数字证书编程指南X509Certificate / X509CertificateRequest / X509Name 全解析仓颉 stdx.crypto.x509 数字证书编程指南X509Certificate / X509CertificateRequest / X509Name文档知识库教程OpenHarmony上一篇GBrain Skillpack 参考架构面向生产环境 AI Agent 的知识中枢设计下一篇在 MCP Python SDK 中构建 MCP Apps让工具拥有交互式 HTML 界面创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考