Closed Lonzak closed 6 months ago
I'm not that pro in encryption. But to leave the code consistent, one should add the different algorithms in the algorithmNames-Map. And this seems to be the case already:
algorithmNames.put(ID_ECDSA, "ECDSA");
algorithmNames.put("1.2.840.10045.4.1", "ECDSA");
algorithmNames.put("1.2.840.10045.4.3", "ECDSA");
algorithmNames.put("1.2.840.10045.4.3.2", "ECDSA");
algorithmNames.put("1.2.840.10045.4.3.3", "ECDSA");
algorithmNames.put("1.2.840.10045.4.3.4", "ECDSA");
There are some differences between this map, and the one you posted. I don't know which are the correct ones.
I wouldn't put too much logic in the constructor, and maybe extending getEncodedPKCS7()
could be the best choice.
@Lonzak
Any idea?
iText eventually fixed this (and added support for other algorithms like RSASSA-PSS and Edwards Curves) in version 8. There were more changes than just to PdfPKCS7
; but this may also only concern the improved signing API layer iText has had since version 5.3.x.
For the SHAxxxWITHECDSA OIDs it should suffice to map that in getEncodedPKCS7
.
@asturio
The code not only creates signatures but also verifies them. For signing with SHAxxxWITHECDSA one needs a map from hash algorithm to OID as proposed by Lonzak. For validation one needs a map from OID to signing algorithm which you found.
There is a small asymmetry between Lonzak's map and the one you found. Here Lonzak's makes more sense, 1.2.840.10045.4.3 is the parent OID for all ecdsa-with-sha2 combinations, but a signature is expected to contain the specific algorithm. Thus, If you have a signature claiming a signature algorithm 1.2.840.10045.4.3, it strictly speaking is invalid. 1.2.840.10045.4.3.1, on the other hand, indeed is SHA224WITHECDSA.
At least, therefore, an entry for 1.2.840.10045.4.3 should be added to the map you found.
@mkl-public Can you take a look? I implemented a fix for the issue. Your opinion would be appreciated...
I have one more question: Does for ECDSA the hash/digest algorithm of the certificate need to correlate with the pdf signature? So e.g. if a 384-Bit-ECDSA key is part of a certificate which is SHA-384 signed - can the pdf signature e.g. use SHA-256? If yes then the oid of SHA-256 must be used?
I don't know of such rule or limitation.
The only thing I can think of in this direction is is for Ed25519 and Ed448 curves which do not use a separate hashing algorithm to prepare the message before signing, unlike algorithms such as RSA or ECDSA, which can be combined with different hashing algorithms. Instead, the hashing mechanism is an integral part of the signature process and is based on SHA-512 for Ed25519 and SHAKE256 for Ed448, leaving no choice for the hashing algorithm.
I have one more question: Does for ECDSA the hash/digest algorithm of the certificate need to correlate with the pdf signature? So e.g. if a 384-Bit-ECDSA key is part of a certificate which is SHA-384 signed - can the pdf signature e.g. use SHA-256? If yes then the oid of SHA-256 must be used?
I don't know of such rule or limitation.
First of all, in general the the way a certificate is signed does not relate to the way it (or more exactly, its associated private key) may sign. The certificate is signed by its issuer certificate which may make use of completely different algorithms. The obvious exception are self-signed certificates.
So I assume here the underlying question is whether there are restrictions which hash algorithms may be used when signing with a key pair generated for a given elliptic curve.
To answer this: Conceptually you can use arbitrary hash algorithms together with any curve; if the calculated hash value is too large, the top bits will simply be cut off. Nonetheless, many combinations don't make sense security-wise. Thus, RFC 5480 ("Elliptic Curve Cryptography Subject Public Key Information") in section 4 ("Security considerations") lists HASH algorithm and elliptic curve combinations ensuring a given degree of security:
Minimum | ECDSA | Message | Curves
Bits of | Key Size | Digest |
Security | | Algorithms |
---------+----------+------------+-----------
80 | 160-223 | SHA-1 | sect163k1
| | SHA-224 | secp163r2
| | SHA-256 | secp192r1
| | SHA-384 |
| | SHA-512 |
---------+----------+------------+-----------
112 | 224-255 | SHA-224 | secp224r1
| | SHA-256 | sect233k1
| | SHA-384 | sect233r1
| | SHA-512 |
---------+----------+------------+-----------
128 | 256-383 | SHA-256 | secp256r1
| | SHA-384 | sect283k1
| | SHA-512 | sect283r1
---------+----------+------------+-----------
192 | 384-511 | SHA-384 | secp384r1
| | SHA-512 | sect409k1
| | | sect409r1
---------+----------+------------+-----------
256 | 512+ | SHA-512 | secp521r1
| | | sect571k1
| | | sect571r1
---------+----------+------------+-----------
To prevent unnecessary processing power consumption and to promote interoperability, that RFC continues and recommends the well-known choices:
Minimum | ECDSA | Message | Curves
Bits of | Key Size | Digest |
Security | | Algorithms |
---------+----------+------------+-----------
80 | 192 | SHA-256 | secp192r1
---------+----------+------------+-----------
112 | 224 | SHA-256 | secp224r1
---------+----------+------------+-----------
128 | 256 | SHA-256 | secp256r1
---------+----------+------------+-----------
192 | 384 | SHA-384 | secp384r1
---------+----------+------------+-----------
256 | 512 | SHA-512 | secp521r1
---------+----------+------------+-----------
That RFC focuses on the NIST curves.
Similarly RFC 5639 ("Elliptic Curve Cryptography (ECC) Brainpool Standard Curves and Curve Generation") recommends the following combinations for Brainpool curves:
+--------------------+--------------------+-------------------------+
| elliptic curve | minimum length of | hash functions |
| domain parameters | symmetric keys | |
+--------------------+--------------------+-------------------------+
| brainpoolP160r1 | 80 | SHA-1, SHA-224, |
| | | SHA-256, SHA-384, |
| | | SHA-512 |
| | | |
| brainpoolP192r1 | 96 | SHA-224, SHA-256, |
| | | SHA-384, SHA-512 |
| | | |
| brainpoolP224r1 | 112 | SHA-224, SHA-256, |
| | | SHA-384, SHA-512 |
| | | |
| brainpoolP256r1 | 128 | SHA-256, SHA-384, |
| | | SHA-512 |
| | | |
| brainpoolP320r1 | 160 | SHA-384, SHA-512 |
| | | |
| brainpoolP384r1 | 192 | SHA-384, SHA-512 |
| | | |
| brainpoolP512r1 | 256 | SHA-512 |
+--------------------+--------------------+-------------------------+
@Lonzak, is this now solved with your PR?
Yes - my last question was not (directly) related to my implementation but more of an understanding for the overall topic...
I just stumbled over the following issue described here. It is the same for openPDF.
It seems that openPDF is always using "1.2.840.10045.2.1" as an oid which is wrong.
So I added a new Hashmap in the PdfPKCS7 class called
ecdsaOids
. Depending on the exact hash of the keys used it needs to be mapped to the following oids:Now I am a bit uncertain where to set it:
Already in the constructor:
or in the getEncodedPKCS7() method:
@mkl-public Any idea?