- 文档
- 知识库
- 教程
- OpenHarmony
【免费下载链接】CangjieCorpus
本仓库为仓颉编程语言语料库,聚焦 仓颉编程语言 核心知识体系,整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源,经结构化处理与专业标注,构建为支持 RAG(检索增强生成)技术 的高质量知识基座,适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用,推动鸿蒙开发生态智能化升级!
导读
stdx.crypto.keys是仓颉标准库扩展(stdx)中面向非对称加密与签名的核心包,支持 RSA、SM2 非对称加密算法以及 ECDSA 签名算法。在使用 RSA 密钥执行加密、解密、签名与验签时,填充模式(Padding)直接决定算法的安全等级与适用场景,而本文要讲解的OAEPOption与PSSOption两个结构体,正是 RSA 两种高强度填充模式 OAEP(最优非对称加密填充)与 PSS(概率签名方案)的参数配置载体。读完本文,你将掌握这两个结构体的完整字段语义、合法取值边界、异常触发条件,并能在真实的加密/签名代码中正确组合使用它们。
一、定位:填充参数结构体在 keys 包中的角色
在 keys 包总览 中,结构体一共有两个,正是OAEPOption与PSSOption,其 API 列表明确标注:
OAEPOption——最优非对称加密填充;PSSOption——概率签名方案。
它们与 PadOption 枚举 直接绑定。PadOption是 RSA 填充模式的入口类型:
public enum PadOption { | OAEP(OAEPOption) | PSS(PSSOption) | PKCS1 }从枚举定义可以看出,OAEP与PSS两个枚举成员各自携带一个结构体参数,而PKCS1不携带任何参数。也就是说,当开发者在 RSA 的公钥加密、私钥解密、私钥签名、公钥验签等方法中通过padType:命名参数指定填充模式时,需要先构造对应的 Option 结构体实例。
三种填充模式的适用范围与安全取向
结合 PadOption 枚举 的说明:
| 填充模式 | 全称 | 适用操作 | 安全说明 |
|---|---|---|---|
OAEP | 最优非对称加密填充(Optimal Asymmetric Encryption Padding) | 仅加密、解密 | 基于随机化填充,具备可证明安全性 |
PSS | 概率签名方案(Probabilistic Signature Scheme) | 仅签名、验证 | 基于随机化盐值,抗伪造能力强 |
PKCS1 | PKCS #1 v1.5 填充 | 加密、解密、签名、验证均可 | 早期规范定义的填充,针对它的攻击手段已较成熟,易被攻击者解密或伪造签名 |
文档明确给出安全建议:应优先采用 PKCS #1 v2 版本中更加安全的 PSS 或 OAEP 填充模式,避免使用 PKCS1。这一建议在 RSA 密钥类 的方法签名中也有呼应:RSAPublicKey.encrypt/RSAPrivateKey.decrypt只接受PKCS1或OAEP(不支持PSS),而RSAPrivateKey.sign/RSAPublicKey.verify只接受PKCS1或PSS(不支持OAEP)。因此,给加密操作传 PSS 参数、给签名操作传 OAEP 参数都是错误的用法,设置填充模式失败时会抛出CryptoException。
二、struct OAEPOption:OAEP 填充参数
OAEPOption是 OAEP 填充模式 需要设置的参数结构体,其完整定义如下:
public struct OAEPOption { public init(hash: Digest, mgfHash: Digest, label!: String = "") }init(Digest, Digest, String) 参数逐项解析
| 参数 | 类型 | 是否可选 | 默认值 | 作用 |
|---|---|---|---|---|
hash | Digest | 必填 | 无 | 摘要方法,用于对label进行摘要 |
mgfHash | Digest | 必填 | 无 | 摘要方法,用于设置 MGF1 函数中的摘要方法 |
label! | String | 可选(带!后缀) | "" | 可选的关联标签,用于区分不同的加密操作 |
其中Digest是仓颉标准库中消息摘要算法的抽象类型,来自std.crypto.digest包。在 digest 包 中,Digest的具体实现包括MD5、SHA1、SHA224、SHA256、SHA384、SHA512、SM3以及带密钥的HMAC。以 SHA1、SHA256、SHA512 为代表的这些类均直接<: Digest,因此可以直接作为hash/mgfHash传入。
参数背后的密码学语义
hash与label的关系:OAEP 填充允许携带一个可选的公开标签(label),其语义是“将标签与密文绑定”——即只有知道该标签的接收方才能正确解密,可用于区分同一把密钥下的不同加密操作(如不同业务场景)。hash摘要方法负责对该 label 进行摘要计算后参与 OAEP 编码。mgfHash与 MGF1 的关系:OAEP 在填充过程中需要将种子扩展为与数据块等长的掩码,这一扩展过程由掩码生成函数MGF1完成。mgfHash就是 MGF1 内部使用的哈希函数,实践中应选用与hash同族或强度不低于它的摘要算法。从源码结构看,mgfHash参数的存在意味着 OAEP 允许“label 摘要”与“掩码生成摘要”使用不同的算法,为开发者提供了更细粒度的配置能力。
实战:使用 OAEPOption 配置 RSA 加密与解密
keys 使用示例 中给出了完整的 RSA + OAEP 加解密流程:
import stdx.crypto.keys.* import stdx.crypto.digest.* import std.io.* import std.crypto.digest.* main() { var rsaPri = RSAPrivateKey(2048) var rsaPub = RSAPublicKey(rsaPri) var str: String = "hello world, hello cangjie" var bas1 = ByteBuffer() var bas2 = ByteBuffer() var bas3 = ByteBuffer() bas1.write(str.toArray()) var encOpt = OAEPOption(SHA1(), SHA256()) rsaPub.encrypt(bas1, bas2, padType: OAEP(encOpt)) var encOpt2 = OAEPOption(SHA1(), SHA256()) rsaPri.decrypt(bas2, bas3, padType: OAEP(encOpt2)) var buf = Array<Byte>(str.size, repeat: 0) bas3.read(buf) if (str.toArray() == buf) { println("success") } else { println("fail") } }运行结果:
success要点拆解:
- 先以 2048 位生成
RSAPrivateKey,再从其构造RSAPublicKey; - 构造
OAEPOption(SHA1(), SHA256()):hash取SHA1()用于 label 摘要(label 缺省为空串),mgfHash取SHA256()用于 MGF1 掩码生成; - 公钥侧
rsaPub.encrypt(bas1, bas2, padType: OAEP(encOpt))加密,私钥侧rsaPri.decrypt(bas2, bas3, padType: OAEP(encOpt2))解密; - 加解密两侧的
OAEPOption参数可以相同也可以不同(示例中两侧各自构造了一份),但解密方必须持有与加密约定一致的label才能正确还原数据。
三、struct PSSOption:PSS 填充参数
PSSOption是 PSS 填充模式 需要设置的参数结构体,其完整定义如下:
public struct PSSOption { public init(saltLen: Int32) }init(Int32) 参数与取值范围
| 参数 | 类型 | 取值范围 | 作用 |
|---|---|---|---|
saltLen | Int32 | 大于等于 0,且小于等于(RSA 密钥长度 - 摘要长度 - 2) | 随机盐长度,单位:字节 |
PSS 之所以被称为“概率签名方案”,核心就在于签名时引入随机盐(salt):同一消息每次签名得到的密文不同,从而抵抗已知签名伪造类攻击。saltLen正是这条随机盐的长度。文档对取值范围给出了明确的边界说明:
- 下限:必须大于等于 0。若小于 0,构造
PSSOption时会抛出 CryptoException; - 上限:不得大于
RSA 密钥长度 - 摘要长度 - 2。若盐过长,会导致签名失败。
从密码学实现角度看,上限公式的含义是:RSA 模长(如 2048 位 = 256 字节)需要容纳:一个与hash摘要等长的“哈希值”、一个与saltLen等长的盐值、若干固定标记字节(至少 2 字节的格式开销),三者之和不能超过模长,否则 PSS 编码无法完成、签名必然失败。
实战:使用 PSSOption 配置 RSA 签名与验签
继续沿用 keys 使用示例 中的思路(该示例默认使用PKCS1,将padType:替换为PSS(PSSOption(...))即可切换到 PSS 签名)。签名验签的标准流程为:
- 使用
SHA512()等摘要算法对消息做摘要(write写入数据、finish()取出摘要字节); - 私钥调用
sign(hash, digest, padType:)完成签名; - 公钥调用
verify(hash, digest, sig, padType:)验证签名,返回Bool。
例如,对 2048 位 RSA 密钥配合 SHA-256(摘要长度 32 字节),saltLen的可选上界约为256 - 32 - 2 = 222字节,实际使用时可依据摘要长度按公式推导。值得注意的是,RSAPrivateKey.sign/RSAPublicKey.verify的参数中hash用于标记获取摘要所用算法,padType仅支持PKCS1或PSS,传OAEP会抛出CryptoException。
四、异常与依赖:使用前的两个前置检查
异常语义:CryptoException
两个结构体的构造函数在参数非法时统一抛出 CryptoException。该异常类定义于stdx.crypto.digest包,是crypto系列包中摘要与加解密出现错误时的通用异常,支持无参构造与带message构造:
public class CryptoException <: Exception { public init() public init(message: String) }具体到本文场景:PSSOption的saltLen < 0会抛出该异常;OAEPOption/PSSOption配合 RSA 使用时,若填充模式设置失败(如加解密传了PSS、签名验签传了OAEP、盐长度越界导致签名失败)同样会抛出该异常。
运行环境依赖:OpenSSL 3
keys 包(以及其依赖的 digest 包)依赖外部 OpenSSL 3 的 crypto 动态库。根据 keys 包总览 的说明,不同平台需满足:
- Linux:安装 OpenSSL 3 开发工具包(如 Ubuntu 22.04 下
sudo apt install libssl-dev),确保存在libcrypto.so与libcrypto.so.3;自定义安装路径时需把目录加入LD_LIBRARY_PATH与LIBRARY_PATH; - Windows:安装 x64 的 OpenSSL 3.x.x 软件包,确保存在
libcrypto.dll.a(或libcrypto.lib)与libcrypto-3-x64.dll,并分别配置LIBRARY_PATH与PATH环境变量; - macOS:
brew install openssl@3安装,确保存在libcrypto.dylib与libcrypto.3.dylib;自定义路径需配置DYLD_LIBRARY_PATH与LIBRARY_PATH。
若未安装或版本过低,程序将抛出类似CryptoException: Can not load openssl library or function xxx的异常。
五、关联阅读:把 Option 结构体放入完整密钥体系
理解OAEPOption/PSSOption之后,建议结合以下仓库文档串起完整链路:
- keys 包 API 类文档:
RSAPrivateKey(支持decrypt、sign,PEM/DER 编解码)、RSAPublicKey(支持encrypt、verify),以及ECDSAPrivateKey/ECDSAPublicKey、SM2PrivateKey/SM2PublicKey; - Curve 枚举:ECDSA 密钥生成时可选的 NIST P-224/256/384/521 与 Brainpool P-256/320/384/512 八种椭圆曲线;
- digest 包:
hash/mgfHash参数所使用的Digest实现(MD5、SHA 系列、SM3、HMAC); - x509 包 PemEntry / DerBlob:密钥通过
encodeToPem()/encodeToDer()导出时对应的数据结构,PemEntry内置LABEL_RSA_PRIVATE_KEY、LABEL_SM2_PRIVATE_KEY、LABEL_PUBLIC_KEY等标准标签; - keys 使用示例:RSA(OAEP 加解密、PKCS1 签名验签)、ECDSA(P224 签名验签)、SM2(加解密、签名验签、PEM 导入导出)三套完整可运行示例。
总结
OAEPOption与PSSOption是stdx.crypto.keys包中 RSA 高强度填充模式的参数门面:前者通过hash+mgfHash+ 可选label三要素控制 OAEP 编码,后者通过saltLen控制 PSS 随机盐长度。掌握它们的字段语义与取值范围,并严格遵循“加密/解密用 OAEP、签名/验签用 PSS”的配对规则,是写出安全、可用的仓颉 RSA 代码的关键一步。
- 文档
- 知识库
- 教程
- OpenHarmony
【免费下载链接】CangjieCorpus
本仓库为仓颉编程语言语料库,聚焦 仓颉编程语言 核心知识体系,整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源,经结构化处理与专业标注,构建为支持 RAG(检索增强生成)技术 的高质量知识基座,适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用,推动鸿蒙开发生态智能化升级!
相关推荐
仓颉 stdx.crypto.keys 填充参数结构体详解:OAEPOption 与 PSSOption 的配置原理与实战
仓颉 stdx.crypto.keys 填充参数结构体详解:OAEPOption 与 PSSOption 的配置原理与实战 导读 stdx.crypto.key
标准库网络密码学并发编程cangjie_stdx 密钥包结构体详解:OAEPOption 与 PSSOption 的 RSA 填充参数配置指南
cangjie_stdx 密钥包结构体详解:OAEPOption 与 PSSOption 的 RSA 填充参数配置指南 本文基于 cangjie_stdx 开源
标准库网络密码学并发编程仓颉 stdx.crypto.keys 密钥枚举详解:Curve 椭圆曲线与 PadOption 填充模式
仓颉 stdx.crypto.keys 密钥枚举详解:Curve 椭圆曲线与 PadOption 填充模式 导读 本文以仓颉标准扩展库 stdx.crypto.
文档知识库教程OpenHarmony
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考