ECDSA 签名

ECDSA DER signature

我在 Java 中生成了一个 ECDSA 签名,我想从中获取 R 和 S 值以获得 COSE 编码的签名。据我了解,我生成的签名是 DER 编码的(默认情况下使用 bouncyCastle)。当我使用 P-256 曲线 (SHA256withECDSA) 时,我正确地检索了 R 和 S 值。

当我使用其他曲线(P-521、P-384)时,我在将签名从一种编码解析为另一种编码时遇到了一些问题。

下面是我解析它的方式:

public static byte[] extractRandSToCose(byte[] signature) {

    if (signature[0] == 0x30) {
        //parse R
        int rSize = signature[3];
        BigInteger rBigInt = new BigInteger(Arrays.copyOfRange(signature, 4, rSize+4));
        //strip out sign byte 0x00
        byte[] r = toByteArrayUnsigned(rBigInt);

        //parse S
        int sSize = signature[5 + rSize];
        int index = rSize + 6;
        BigInteger sBigInt = new BigInteger(Arrays.copyOfRange(signature, index, index+sSize));
        //strip out sign byte 0x00
        byte[] s = toByteArrayUnsigned(sBigInt);

        return Bytes.concat(r,s);
    }
    return null;
}


public static byte[] toByteArrayUnsigned(BigInteger bigInteger) {
    byte[] extractedBytes = bigInteger.toByteArray();
    int skipped = 0;
    boolean skip = true;
    for (byte b : extractedBytes) {
        boolean signByte = b == 0x00;

        if (skip && signByte) {
            skipped++;
            continue;
        } else if (skip){
            skip = false;
        }
    }
    extractedBytes = Arrays.copyOfRange(extractedBytes, skipped, extractedBytes.length);
    return extractedBytes;
}

我不明白我做错了什么。

PS: Those methods works from time to time. It works everytime for P-256 (whether the DER signature is 70 71 or 72 bytes long and properly gives me a 64 byte long Cose signature), P-384 (same for 102, 103 104 byte long and properly gives me a 96 byte long cose signature) but only works half the time for P-521 (138, 139, 140 byte long and even when it does the cose signature is only 31 byte long....)

{hash}withECDSAinP1363Format 成功了!谢谢 !我什至不需要阅读所有这些规范来了解如何解析它...