5

我有使用 BouncyCastle 由 SHA1withECDSA 算法签名的自签名证书。在 BC 下,我可以轻松验证它,但是当我在 JavaCard 上进行验证时,它每次都会向我发送错误消息(来自 NIST 的曲线 secp192r1)。证书持有普通签名(非 X9.62 意味着只有 r+s 没有任何标签)。

有我的代码来验证它(将值设为常量 - 当然用于测试)。

字节 [] 证书数据 = {...}

    Signature signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
    ECPublicKey ecpk = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC,      KeyBuilder.LENGTH_EC_FP_192, true);

    ecpk.setA(new byte[]{...}, (short)0, (short)0x0018); 
    ecpk.setB(new byte[]{...}, (short)0, (short)0x0018);
    ecpk.setG(new byte[]{...}, (short)0, (short)0x0031);
    //Point format: uncompressed tag(0x04), x, y
    ecpk.setK((short)0x0001);
    ecpk.setR(new byte[]{}, (short)0, (short)0x0018);
    ecpk.setW(new byte[]{}, (short)0, (short)0x31);
    ecpk.setFieldFP(new byte[]{}, (short)0, (short)0x0018);

    signature.init(ecpk, Signature.MODE_VERIFY);

    boolean result = signature.verify(certdata, (short)0, (short)certdata.length, signtab, (short)0, (short)signtab.length);
    if(result) ISOException.throwIt((short)0x0001);
    else ISOException.throwIt((short)0x0002);    
}

'...' 而不是字节以获得清晰的视图(192 位曲线可能会造成很大的混乱)。

pastebin 上带有标签说明的证书:

http://pastebin.com/gvqYzm2g

谢谢你的帮助

塞瓦尔

编辑:新测试:所有测试都基于相同的数据(PublicKey、PrivateKey、要签名的消息)符号是随机的,所以我将使用 2 个符号(signT - 终端 (BC) 生成的符号,signC - 芯片生成的符号)

signT 不能在 CHIP 上验证,但可以在终端上验证。signC 在芯片和终端上验证

所以我检查了API之间的交叉

  • 指向 BC 的交叉关系运行良好

  • 指向 CHIP 的交叉关系不起作用

一对密钥生成得很好,因为当我将 BC 生成的 PrivateKey 和 PublicKey 放入 CHIP 时,CHIP 上生成的签名可以被 CHIP 验证。

  • KeyPair 生成良好

我不知道我现在应该检查什么。问题可能与在 ECDSA 步骤 e = SHA1(Message) 中填充数组有关。哈希后数组发生了什么(哈希比曲线短,卡片需要在复制前声明数组的大小)

4

2 回答 2

0

我在使用 BouncyCastle 验证 ECDSA 签名(在 JavaCard 192r1 上生成)时遇到问题,我找到了解决方案。我希望它会有用

在充气城堡上验证 javacard 签名 ALG_ECDSA_SHA

于 2015-03-05T21:12:43.073 回答
0

从 Bouncy Castle 到 JavaCard 使用 Prime192v1 对 ECDSAwithSHA-1 进行签名和验证对我来说效果很好。

您的问题可能是签名本身的格式。

签名是 DER 编码结构,它是两个整数(标签 0x02)的序列(标签 0x30)。在 JavaCard 中,总是需要 56 个字节:两个长度为 25 的坐标加上 6 个字节的 DER 标头。JavaCard 总是期望每个坐标中有前导零。但是,BC 生成的签名通常在坐标中没有前导零,因此签名可以短于 56 个字节,这就是 JavaCard 混淆的原因。

相反的方向总是可以的,因为 BC 可以处理前导零,尽管它在创建签名时不会添加它们。

您应该做什么:用您自己的代码包装 BC 签名机制,并始终在您的 BC 签名中的坐标中添加前导零。如果这样做,您将能够在 BC 和 JavaCard 中验证签名。

我想发布我的代码,但不幸的是它是商业安全项目的一部分......

于 2014-12-17T09:12:56.157 回答