Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6578658

Request for raw RSA (NONEwithRSA) Signature support in SunMSCAPI

XMLWordPrintable

    • b142
    • generic, x86
    • generic, windows_xp
    • Not verified

        A DESCRIPTION OF THE REQUEST :
        Requesting support for doing raw RSA signing with SunMSCAPI - at present only SHA-1, MD5 and MD2 signing is possible.

        This would include the SunMSCAPI provider having the following property or similar:

        Signature.NONEwithRSA=sun.security.mscapi.RSASignature$NONE

        Alternatively, the SunMSCAPI cipher class could be changed to support encrypting with private keys, although i suspect that the underlying MSCAPI doesn't allow that.

        JUSTIFICATION :
        NONEwithRSA Signing is required by JSSE for client authentication enabled SSL. At the moment because SunMSCAPI doesn't include a NONEwithRSA property, the default NONEwithRSA signature class is being used. This class merely wraps the cipher class - and the MSCAPI cipher class doesn't support encrypting with private keys. A "Bad Key" exception results.

        See: http://forum.java.sun.com/thread.jspa?threadID=5188515&tstart=0

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        After setting a client application to use the Windows key and trust stores in the normal manner, and given that the server and client trust each other's certificates, using JSSE to connect to a server using SSL with client authentication should work.
        ACTUAL -
        The following error is thrown during the client verification stage, on the client end:

        Exception in thread "main" javax.net.ssl.SSLException: java.security.ProviderException: java.security.KeyException: Bad Key.
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1520)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1487)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1470)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1396)
        at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:64)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
        at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
        at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
        at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
        at SunMSCAPITest.main(SunMSCAPITest.java:37)
        Caused by: java.security.ProviderException: java.security.KeyException: Bad Key.

        at sun.security.mscapi.RSACipher.doFinal(RSACipher.java:242)
        at sun.security.mscapi.RSACipher.engineDoFinal(RSACipher.java:266)
        at javax.crypto.Cipher.doFinal(DashoA13*..)
        at java.security.Signature$CipherAdapter.engineSign(Signature.java:1225)
        at java.security.Signature$Delegate.engineSign(Signature.java:1128)
        at java.security.Signature.sign(Signature.java:522)
        at com.sun.net.ssl.internal.ssl.RSASignature.engineSign(RSASignature.java:149)
        at java.security.Signature$Delegate.engineSign(Signature.java:1128)
        at java.security.Signature.sign(Signature.java:522)
        at com.sun.net.ssl.internal.ssl.HandshakeMessage$CertificateVerify.<init>(HandshakeMessage.java:1216)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:715)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:197)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:511)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:449)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:817)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1029)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:621)
        at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
        ... 6 more
        Caused by: java.security.KeyException: Bad Key.

        at sun.security.mscapi.RSACipher.encryptDecrypt(Native Method)
        at sun.security.mscapi.RSACipher.doFinal(RSACipher.java:222)
        ... 23 more

        ---------- BEGIN SOURCE ----------
        import java.io.BufferedReader;
        import java.io.InputStreamReader;
        import java.io.OutputStreamWriter;
        import java.io.Writer;
        import java.net.Socket;

        import javax.net.ssl.SSLSocketFactory;

        public class SunMSCAPITest {

        // Website to access
        public static final String TARGET_HTTPS_SERVER = "localhost";
        public static final int TARGET_HTTPS_PORT = 8443;

        public static void main(String[] args) throws Exception {

        System.setProperty("javax.net.ssl.keyStoreProvider","SunMSCAPI");
        System.setProperty("javax.net.ssl.keyStoreType","Windows-MY");
        System.setProperty("javax.net.ssl.trustStoreProvider","SunMSCAPI");
        System.setProperty("javax.net.ssl.trustStoreType","Windows-ROOT");

        Socket socket = SSLSocketFactory.getDefault().createSocket(TARGET_HTTPS_SERVER,
        TARGET_HTTPS_PORT);

        try {
        Writer out = new OutputStreamWriter(socket.getOutputStream(),
        "ISO-8859-1");
        out.write("GET / HTTP/1.1\r\n");
        out.write("Host: " + TARGET_HTTPS_SERVER + ":" + TARGET_HTTPS_PORT
        + "\r\n");
        out.write("Agent: SSL-TEST\r\n");
        out.write("\r\n");
        out.flush();
        BufferedReader in = new BufferedReader(new InputStreamReader(socket
        .getInputStream(), "ISO-8859-1"));
        String line = null;
        while ((line = in.readLine()) != null) {
        System.out.println(line);
        }
        } finally {
        socket.close();
        }
        }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        At the moment this can be worked around by setting both the client and server applications to use one of the other signature types instead of NONEwithRSA:

        i.e.
        Provider p = Security.getProvider("SunMSCAPI");
        p.setProperty("Signature.NONEwithRSA","sun.security.mscapi.RSASignature$SHA1");

        This isn't always possible to do on the server end though, and breaks SSL compatibility.

              vinnie Vincent Ryan
              ndcosta Nelson Dcosta (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: