【问题标题】:PGP data encryption for use with Yubico OpenPGP Smart Card用于 Yubico OpenPGP 智能卡的 PGP 数据加密
【发布时间】:2015-11-21 08:36:18
【问题描述】:

我正在尝试在 Java 应用程序中实现基于 Yubikey NEO OpenPGP 智能卡小程序的 PGP 加密。这似乎是一门黑暗的艺术,用谷歌搜索这些东西并不容易,但这是我到目前为止的地方:

  1. 卡已初始化,使用 gpg 工具生成密钥。它通常有效。我有.asc 格式的公钥并设法将其加载到org.bouncycastle.openpgp

  2. 使用javax.smartcardio API 连接到 USB 加密狗中的智能卡。

  3. 选择 OpenPGP 小程序

    val pgpAID = bytes(0xD2, 0x76, 0x00, 0x01, 0x24, 0x01)
    val answer = cardChannel.transmit(CommandAPDU(0x00, 0xA4, 0x04, 0x00, pgpAID))
    
  4. 成功向卡出示正确的 PIN

    val pin = "123456"
    return bytes(0x00, 0x20, 0x00, 0x82, pin.length) + pin.toByteArray(Charsets.UTF_8)
    
  5. 发送一个准成功(见下文)decipher 命令

    bytes(0x00, 0x2a, 0x80, 0x86, data.size) + data + bytes(0x00)
    

    data = "xxxx".toByteArray() 时,结果为SW=9000(= 成功)但没有返回数据。这是一个幼稚的测试,因为第 52 页上的 OpenPGP applet documentation 提到了这一点

    命令输入(填充指示字节除外)应为 加密前根据PKCS#1格式化。

我不知道如何加密数据并将其转换为 PKCS#1 格式。

我也尝试阅读Yubico OpenPGP card implementation tests,但它只提供了另一个“失败”示例(第 196 行)。我尝试运行它,但结果不同:测试需要SW=0050(表示异常?),我得到的是SW=6f00(没有精确诊断,根据this document)。

我用整个代码创建了一个GitHub repository。它是用 Kotlin 编写的,但应该易于阅读。

【问题讨论】:

  • 哦,你这里已经有问题了。请注意,您可能希望使用 T=1 协议而不是 T=0 进行连接,并且并非所有卡都支持扩展长度。否则,您可能需要查看 ISO/IEC 7816-4 命令链接

标签: java encryption smartcard openpgp yubico


【解决方案1】:

您的问题有些困惑,但我很确定您想使用与智能卡上的 RSA 私钥相对应的 RSA 公钥创建 PGP 加密消息,然后使用智能卡上的 RSA 私钥(帮助)解密它们. PGP(几乎与其他所有内容一样)使用混合加密,因此相关部分的 PGP 加密消息包括:

  • 使用随机生成的工作密钥使用适当的对称算法(如 TDES 或 AES)加密的实际消息,称为 K
  • 工作密钥 K 加上一些由 RSA 使用接收者的公钥加密的元数据和原始 PKCS#1 标准定义的填充,现在正式称为 RSAES-PKCS1-v1_5,但仍被广泛称为 PKCS1,有些不准确。

您不需要执行加密步骤,因为任何实现该标准的软件都可以这样做,包括 GnuPG 或 BouncyCastle 的 bcpg 库。如果您想自己做,也许对于使用伪造的 K 而没有真实消息的测试数据,您需要进行填充 RSA 模幂运算;在 Java 中,至少是带有标准加密提供程序的 Oracle 或 openjdk Java,您可以按照通常的方式使用通过.getInstance("RSA/ECB/PKCS1Padding") 获得的javax.crypto.Cipher

“PKCS1”加密填充(用于 RSA)如该文档第 52 页底部和第 53 页顶部所述,其内容相同,但格式与 current OpenPGP spec 不同(和更早的版本),它指的是near-current PKCS#1 spec(和更早版本)并且实际上与near-current PKCS#1 spec(和更早版本)相同,所有这些都说它是:

  • 一个字节00
  • 一个字节02
  • 足够的非零随机字节使结果长度正确且安全
  • 一个字节00
  • “明文”,对于 PGP 加密,它实际上是工作对称密钥 K,其格式为 the PGP spec 中指定的格式。

注意段落开头

如果是 AES 算法

似乎用于不同的选项,而不是 PGP AFAICS,在上一页中描述为

通过选项(在扩展功能中宣布)该卡支持对普通的解密 带有存储在特殊 DO (D5) 中的 AES 密钥的文本。如果没有证书或公共的,这很有用 密钥存在且外部世界与卡有共同的秘密。

所以忽略它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 2020-01-04
    相关资源
    最近更新 更多