椭圆曲线数字签名格式



有一个基于Java库github/esig/dss的应用程序,其目标是向PDF文件添加远程签名。不同的方法创建不同格式的签名。如何在它们之间转换?特别是如何将pkcs11格式转换为ASN1?

如果PKCS11与智能卡一起使用,则sha256哈希53EDC760B766E1F4D8B0C5715725EE447B79C02F7759C52AD3D36EADD29C10A会生成类似3066023100ba193a7a87666ebd0f923b7368eeb536b88de47834049d3ed3baf70a23635ac9b73f671bf944b36332754a434f9de023100d4984ef9f4ef61eec28f73ce6f5d8f7a391420c8f21cc018641f5b54f600458f2d2f823e632ab017fa041e58d48a3f的签名算法ECDSA_sha256

这是合适的ASN1结构

$ openssl asn1parse -inform der -in signature.bin
0:d=0  hl=2 l= 102 cons: SEQUENCE          
2:d=1  hl=2 l=  49 prim: INTEGER           :BA193A7A87666EBD0F923B7368BEEB536B88DE47834049D3ED3BAF70A23635AC9B73F671BEEF944B36332754A434F9DE
53:d=1  hl=2 l=  49 prim: INTEGER           :D4984EF9F4EF61EEC28F73CEE6F5D8F7A391420C8F21FCC018641F5B54F600458F2D2F823E632AB017FA041E58D48A3F

但是,使用pkcs11工具从CLI创建签名时,签名长度不同,因此格式不同。如何将此格式转换为ASN1-der格式?

$ echo "53EDC760B7A66E1F4D8B0C5715725EE447B79C02F7759C52AD3D36EADD29C10A" |pkcs11-tool -s --slot 1 -p <PIN> |xxd -p -c96
Using signature algorithm ECDSA
3f8c7060430cae99a048618035548bb7449fd9795cad2d8b3b8888fff78593da79cf39a41314a832dd8bae0b5f86c165775fcee045a477809fa8bb3245330abec22443aa8b5bccb775c32238eda1e8ce31a2a84d67b58dc9e3697c3eb8497f43

经过更多的研究,我从BouncyCastle库中找到了答案。byte[]签名是RS编码的签名,返回值将是ASN.1编码的签名。

static byte[] concatenatedRSToASN1DER(final byte[] signature, int signLength) {
int len = signLength / 2;
int arraySize = len + 1;
byte[] r = new byte[arraySize];
byte[] s = new byte[arraySize];
System.arraycopy(signature, 0, r, 1, len);
System.arraycopy(signature, len, s, 1, len);
BigInteger rBigInteger = new BigInteger(r);
BigInteger sBigInteger = new BigInteger(s);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
DERSequenceGenerator seqGen = new DERSequenceGenerator(bos);
seqGen.addObject(new ASN1Integer(rBigInteger.toByteArray()));
seqGen.addObject(new ASN1Integer(sBigInteger.toByteArray()));
seqGen.close();
bos.close();
} catch (IOException e) {
throw new RuntimeException("Failed to generate ASN.1 DER signature", e);
}
return bos.toByteArray();
}

最新更新