我有使用BouncyCastle的SHA1withECDSA算法签名的自签名证书。 在BC下我可以轻松验证它,但是当我在JavaCard上执行它时,它每次都会发送给我错误(来自NIST的曲线secp192r1)。证书持有标志(非X9.62表示没有任何标签的r + s)。
有我的代码来验证它(将值作为常量 - 当然是为了测试)。
byte [] certdata = {...}
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的TAGS说明证书:
感谢您的帮助
sevar
编辑: 新测试: 所有测试都依赖于相同的数据(PublicKey,PrivateKey,要签名的消息) 标志是随机的,所以我将使用2个符号(signT - 由终端(BC)生成的符号,signC - 由Chip生成的符号)
signT无法在CHIP上验证,但可以在终端上验证。 signC在CHIP&终端
所以我检查了API之间的交叉
针对BC的交叉关系运作良好
针对CHIP的交叉关系不起作用
生成的密钥对很好,因为当我将BC生成的PrivateKey和PublicKey放到CHIP时,CHIP上生成的签名可以通过CHIP验证。
我不知道我现在应该检查什么。问题可能是在ECDSA步骤e = SHA1(消息)中填充数组。哈希后的数组会发生什么(哈希比曲线短,卡需要在复制之前声明数组的大小)
答案 0 :(得分:0)
使用Prime192v1从Bouncy Castle到JavaCard签署和验证ECDSAwithSHA-1对我来说很好。
您的问题可能是签名本身的格式。
签名是DER编码结构,它是两个整数(标记0x02)的序列(标记0x30)。在JavaCard中,总是需要56个字节:两个长度为25的坐标加上6个DER字节的字节。 JavaCard总是希望每个坐标都有前导零。但是,BC通常会在坐标中产生没有前导零的签名,因此签名可能短于56个字节,这就是JavaCard混淆的原因。
相反的方向总是正常,因为BC可以处理前导零,虽然它在创建签名时不会添加它们。
您应该做什么:使用您自己的代码包装BC签名机制,并始终将前导零添加到BC签名中的坐标。如果这样做,您将能够在BC和JavaCard中验证签名。
我想发布我的代码,但遗憾的是它是商业安全项目的一部分......
答案 1 :(得分:0)
我在使用BouncyCastle验证ECDSA唱片(在JavaCard 192r1上生成)时遇到了问题,我发现了一个解决方案。我希望它会有用