如何使用YubiKey .NET SDK解密文本并解决解密异常问题
核心疑问解答
1. 加密字符串每次变化属于正常现象
RSA加密使用OAEP或PKCS#1填充方案时,会内置随机数因子,哪怕明文、公钥完全一致,每次加密输出的密文也会不同,这是密码学标准设计,用于对抗明文攻击,和密钥对是否变化无关。YubiKey PIV槽位的密钥对为永久存储,只要你不主动调用生成接口重新生成,密钥对不会随程序运行变化,完全满足你对外分发公钥的业务需求。
2. 解密抛异常的根本原因
你的两套代码都存在核心逻辑错误:
- 第一套测试方法:你使用
PivSlot.Attestation(槽位号0xF9)的公钥加密,却调用槽位0x9D(密钥管理槽)的私钥解密,两个槽位的密钥对完全独立不匹配,因此触发数据未找到的异常。 - 第二套测试方法:你混淆了签名和加密的能力边界,
pivSession.Sign是私钥签名接口,输出的是签名值而非密文,同时依然存在槽位不匹配问题:用0x9A(认证槽)做签名,却调用0x9D槽做解密,必然报错。
修复建议
- 确定固定的PIV使用槽位,非对称加解密场景标准使用
PivSlot.KeyManagement(槽位号0x9D)即可,加密、解密必须使用同一个槽位的公钥、私钥。 - 若对应槽位尚未生成密钥对,先调用一次
pivSession.GenerateKeyPair(PivSlot.KeyManagement, PivAlgorithm.Rsa2048)生成密钥对,导出公钥留存分发即可,后续无需重复调用生成接口。 - 修正第一套测试方法的公钥获取逻辑,将原代码中的
修改为PivMetadata pivMetadata = pivSession.GetMetadata(PivSlot.Attestation);PivMetadata pivMetadata = pivSession.GetMetadata(PivSlot.KeyManagement); - 移除手动的
Dispose()调用:你已经用using块包裹了PivSession、RSA对象,退出using块会自动释放资源,手动调用Dispose会导致重复释放的潜在问题。 - 第二套测试方法属于逻辑误用:签名的用途是身份认证、防篡改,流程为私钥签名、公钥验签,和加解密的公钥加密、私钥解密流程完全不同,做加解密不要调用签名相关接口。
内容的提问来源于stack exchange,提问作者pshore90
相关产品推荐
相关产品推荐

