Bug 43056 - Library does not allow specify provider for private key operations
Summary: Library does not allow specify provider for private key operations
Status: RESOLVED FIXED
Alias: None
Product: Security - Now in JIRA
Classification: Unclassified
Component: Signature (show other bugs)
Version: Java 1.4.1
Hardware: All All
: P2 normal
Target Milestone: ---
Assignee: XML Security Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-07 15:39 UTC by Alon Bar-Lev
Modified: 2007-12-21 08:59 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alon Bar-Lev 2007-08-07 15:39:13 UTC
Hello,

At src/org/jcp/xml/dsig/internal/dom/DOMRSASignatureMethod.java the Signature 
object is used, but it is initialized without a provider.

[Relevant for decryption]

The problem is that if a hardware based provider is used (One which cannot 
extract its private key), the signature fails.

The expected behavior is to use a specific provider as any other java crypto 
methods.

I know there is an issue with the interface stabilization... But this is a 
required functionality, as there is no security without hardware 
cryptography... And security packages should be the first to support this.

Thanks!
Comment 1 sean.mullan 2007-08-08 08:24:58 UTC
Can you please send more information, such as the exception stack trace and
details of the software you are using (JDK, provider)? Enhancements to JDK 5
were made to specifically address the problems with unextractable keys that
you are reporting. You should not have to specify a specific provider.
For more information, see:
http://java.sun.com/javase/6/docs/technotes/guides/security/p11guide.html#DelayedSelect
Comment 2 Alon Bar-Lev 2007-08-08 08:40:00 UTC
Hello,

I am using sun JVM version 1.5 and 1.6.
I am using the PKCS#11 provider.
This provider provides SHA1withRSA.
Its priority is lower than the default provider that also provides SHA1withRSA.
So the default provider try to perform the RSA operation so it tries to 
translate the PrivateKey into RSAPrivateKey to extract the attribute, and it 
fails.
And for the up-coming question... No... PKCS#11 provider cannot be the first 
one, as many things will go wrong... :)

---

javax.xml.crypto.dsig.XMLSignatureException: java.security.InvalidKeyException: 
Private keys must be instance of RSAPrivate(Crt)Key or have PKCS#8 encoding
        at 
org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:370)
Caused by: java.security.InvalidKeyException: Private keys must be instance of 
RSAPrivate(Crt)Key or have PKCS#8 encoding
        at 
sun.security.rsa.RSAKeyFactory.translatePrivateKey(RSAKeyFactory.java:246)
        at 
sun.security.rsa.RSAKeyFactory.engineTranslateKey(RSAKeyFactory.java:149)
        at sun.security.rsa.RSAKeyFactory.toRSAKey(RSAKeyFactory.java:79)
        at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:90)
        at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:84)
        at java.security.Signature$Delegate.init(Signature.java:1073)
        at java.security.Signature$Delegate.chooseProvider(Signature.java:1033)
        at java.security.Signature$Delegate.engineInitSign(Signature.java:1097)
        at java.security.Signature.initSign(Signature.java:480)
        at 
org.jcp.xml.dsig.internal.dom.DOMRSASignatureMethod.sign(DOMRSASignatureMethod.java:162)
        at 
org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:367)
        ... 2 more
java.security.InvalidKeyException: Private keys must be instance of 
RSAPrivate(Crt)Key or have PKCS#8 encoding
        at 
sun.security.rsa.RSAKeyFactory.translatePrivateKey(RSAKeyFactory.java:246)
        at 
sun.security.rsa.RSAKeyFactory.engineTranslateKey(RSAKeyFactory.java:149)
        at sun.security.rsa.RSAKeyFactory.toRSAKey(RSAKeyFactory.java:79)
        at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:90)
        at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:84)
        at java.security.Signature$Delegate.init(Signature.java:1073)
        at java.security.Signature$Delegate.chooseProvider(Signature.java:1033)
        at java.security.Signature$Delegate.engineInitSign(Signature.java:1097)
        at java.security.Signature.initSign(Signature.java:480)
        at 
org.jcp.xml.dsig.internal.dom.DOMRSASignatureMethod.sign(DOMRSASignatureMethod.java:162)
        at 
org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:367)
java.security.InvalidKeyException: Private keys must be instance of 
RSAPrivate(Crt)Key or have PKCS#8 encoding
        at 
sun.security.rsa.RSAKeyFactory.translatePrivateKey(RSAKeyFactory.java:246)
        at 
sun.security.rsa.RSAKeyFactory.engineTranslateKey(RSAKeyFactory.java:149)
        at sun.security.rsa.RSAKeyFactory.toRSAKey(RSAKeyFactory.java:79)
        at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:90)
        at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:84)
        at java.security.Signature$Delegate.init(Signature.java:1073)
        at java.security.Signature$Delegate.chooseProvider(Signature.java:1033)
        at java.security.Signature$Delegate.engineInitSign(Signature.java:1097)
        at java.security.Signature.initSign(Signature.java:480)
        at 
org.jcp.xml.dsig.internal.dom.DOMRSASignatureMethod.sign(DOMRSASignatureMethod.java:162)
        at 
org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:367)
Comment 3 Alon Bar-Lev 2007-08-08 08:42:41 UTC
BTW:
I hacked the source in order to make it work...

        if (signature == null) {
            /* @HACK BEGIN */
            /*
             * Use a specific provider to perform
             * signature
             */
            java.security.Provider p = 
(java.security.Provider)System.getProperties ().get 
("org.jcp.xml.dsig.internal.dom.signprovider");
            try {
                // FIXME: do other hashes besides sha-1
                if (p == null) {
                        signature = Signature.getInstance("SHA1withRSA");
                }
                else {
                        signature = Signature.getInstance("SHA1withRSA", p);
                }
            } catch (NoSuchAlgorithmException nsae) {
                throw new InvalidKeyException("SHA1withRSA Signature not 
found");
            }
            /* @HACK END */
        }
Comment 4 sean.mullan 2007-08-08 13:04:11 UTC
Please read the bug report at
http://issues.apache.org/bugzilla/show_bug.cgi?id=40826

A similar problem has come up before and it can be caused by using a PrivateKey
from a PKCS#11 provider instance that is passed to the KeyStore API or by
manipulating the providers using the Provider API. In particular, when you
get your PrivateKey from the PKCS11 KeyStore, make sure you do not specify a
specific provider, instead just do the following:

KeyStore.getInstance("PKCS11");
Comment 5 sean.mullan 2007-12-21 08:59:33 UTC
Fixed. In order to use a specific provider, you must pass the Provider object
as a property to the XMLSignContext or XMLValidateContex, ex:

signContext.setProperty
    ("org.jcp.xml.dsig.internal.dom.SignatureProvider", new MyProvider());