bc-java icon indicating copy to clipboard operation
bc-java copied to clipboard

Support for Java 9 signature algorithm names with P1363

Open gino0631 opened this issue 4 years ago • 2 comments

Java 9 introduced new standard algorithm names to support signature algorithms with an output as defined in IEEE P1363 format, e.g. SHA256withECDSAinP1363Format: https://docs.oracle.com/javase/9/docs/specs/security/standard-names.html#signature-algorithms

It would be good if BC provider could support these in Signature.getInstance(algorithm, provider).

gino0631 avatar Jul 16 '20 02:07 gino0631

Hello. Here is a workaround I use.

import org.bouncycastle.jcajce.provider.asymmetric.ec.SignatureSpi;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Provider;
import java.security.Security;

public class BcP1363Provider extends Provider {
    public BcP1363Provider() {
        super("BcP1363", "1.0", "Bouncy Castle - P1363 Bridge");
        put("Signature.SHA256withECDSAinP1363Format", SignatureSpi.ecCVCDSA256.class.getName());
    }
}

Security.insertProviderAt(new BouncyCastleProvider(), 1);
Security.insertProviderAt(new BcP1363Provider(), 1);

robelcik avatar Jul 10 '22 14:07 robelcik

The missing support is specially tricky when Java Sun/JCP XMLSignature implementation is used. Normally you don't have to specify a Provider for Signature.getInstance("algo") to work properly with keys from BouncyCastle, as the internal engineInitSign method will iterate over providers and check with each if it is compatible with.

However with "default" XMLSignature implementation it will resolve a SignatureMethod object - org.jcp.xml.dsig.internal.dom.DOMSignatureMethod.SHA256withECDSA (Java 17) - which has a primary algo in getJCAAlgorithm "SHA256withECDSAinP1363Format" and fallback algo in getJCAFallbackAlgorithm "SHA256withECDSA".

Note that the apache xmlsec implementation - org.apache.jcp.xml.dsig.internal.dom.DOMSignatureMethod.SHA256withECDSA, version 2.2.3 - does not have this dual/fallback algorithm, the only algorithm is knows is "SHA256withECDSA" and thus works "normally" with BC keys.

The issue is in what happens in org.jcp.xml.dsig.internal.dom.DOMSignatureMethod#sign for ECDSA signatures in Java 17. First Signature is successfully obtained with "auto-detected provider" for algo "SHA256withECDSAinP1363Format" in the method org.jcp.xml.dsig.internal.dom.DOMSignatureMethod.AbstractP1363FormatSignatureMethod#getSignature, Later, when the BC ECDSA key is passed to initSign(), the only matching Provider for that signature algo is Sun, but that is not compatible with the BC key!

Fix 1) is what @robelcik suggested - add a custom provider that provides these "inP1363" sig algos from BC.

Fix 2) uses an implementation detail of org.jcp.xml.dsig.internal.dom.DOMSignatureMethod#sign (apache impl does exactly the same) which checks if the XMLSignContext has a property called "org.jcp.xml.dsig.internal.dom.SignatureProvider" and obtains the JCA Provider for the signature from there. That can be done by calling setProperty on DomSignContext (which also contains the key) being passed to the javax.xml.crypto.dsig.XMLSignature#sign method (which eventually calls the DOMSignatureMethod#sign). This will lead to org.jcp.xml.dsig.internal.dom.DOMSignatureMethod.AbstractP1363FormatSignatureMethod#getSignature failing to obtain a Signature object for the "SHA256withECDSAinP1363Format" and instead will create a Signature object for "SHA256withECDSA" algo and note down that the format is "asn1= true", and later does an extra step of converting to the "P1363/XMLDSIG" format in org.jcp.xml.dsig.internal.dom.DOMSignatureMethod.AbstractECDSASignatureMethod#postSignFormat

michkot avatar Aug 22 '23 13:08 michkot