2

For my application, I'm trying to sign some byte contents using java.security.Signature class. The problem I'm having is that signature is never generated at a fixed length. For instance, sometimes it is generated at a length of 135, 136 or 137 bytes. Is there a way to specify the length or some padding at the end? Any other ideas or comments are appreciated.

    private byte[] ecdsaSign(ECPrivateKey key, byte[] content) throws Exception {
                Signature ecdsaSign = Signature.getInstance("SHA256withECDSA", "SC");
                ecdsaSign.initSign(key);
                ecdsaSign.update(content);
                byte[] signature = ecdsaSign.sign();
                return signature;
}
Joel Pou
  • 158
  • 2
  • 13

1 Answers1

3

For ECDSA Java crypto uses the ASN.1 DER encoding standardized by X9.62, SEC1 and rfc 3279 sec 2.2.3, which varies slightly in length. This is covered in more detail on another Stack: https://crypto.stackexchange.com/questions/1795/how-can-i-convert-a-der-ecdsa-signature-to-ASN.1 and https://crypto.stackexchange.com/questions/33095/shouldnt-a-signature-using-ecdsa-be-exactly-96-bytes-not-102-or-103 and https://crypto.stackexchange.com/questions/37528/why-do-openssl-elliptic-curve-digital-signatures-differ-by-one-byte

This is also true for DSA, but not RSA, where signatures (and cryptograms since RSA supports both signature and encryption) are fixed length for a given key, as defined by I2OS and OS2I in PKCS1.

If you want a different encoding, such as the fixed-length one used by PKCS11 (and your provider name "SC" suggests that possibility), you must convert it.

Added 2019-10: you no longer have to do it yourself in Java; BouncyCastle since 1.61 (2019-02) correctly supports this, as does SunEC in Java 9 up (2018-12). See later near-dupe Java ECDSAwithSHA256 signature with inconsistent length .

Community
  • 1
  • 1
dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70
  • Thanks for the response. Really appreciated. I was following a similar approach such as this one https://stackoverflow.com/questions/39385718/der-decode-ecdsa-signature-in-java. I can obtain fixed length R and S values after encoding to ASN1, but this gives me two values. Is there a way to encode these two values into one fixed length sequence like in base64 or other format? – Joel Pou Jan 11 '18 at 23:01
  • @JoelPou: if you need to interoperate with any other program(s) or system(s), you need to use a format compatible with it(them), otherwise you can use any format you like that correctly preserves the values of r and s. The PKCS11 approach is one way, but there are probably hundreds or thousands of other possibilities. Base64 is not a format itself, it is an encoding that can be applied to any format. As one example XMLDSIG uses base64 of concatenated fixed-length r and s. – dave_thompson_085 Jan 14 '18 at 05:01