椭圆曲线数字签名格式

问题描述

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

如果PKCS11与智能卡使用,那么SHA256散列53EDC760B7A66E1F4D8B0C5715725EE447B79C02F7759C52AD3D36EADD29C10A使用算法ECDSA_SHA256

产生签名等3066023100ba193a7a87666ebd0f923b7368beeb536b88de47834049d3ed3baf70a23635ac9b73f671beef944b36332754a434f9de023100d4984ef9f4ef61eec28f73cee6f5d8f7a391420c8f21fcc018641f5b54f600458f2d2f823e632ab017fa041e58d48a3f

这是正确的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-tool从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,r,1,len);
    System.arraycopy(signature,len,s,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();
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...