i have write a applet and signed it. this applet should download a file from a server by https and signed this file and then upload this file to server by https.
the certificate used to signed is the same to establish the connection https.
the orign probleme is: when my applet use a keystore like pkcs12 and jks it works perfectely. but when it try use the keysore of windows, i always get a 
javax.net.ssl.SSLHandshakeException: Received fatal alert: decrypt_errori can not paste all my programme here but i paste the most important.
i got my kstore ks by:
try {
// System.out.println("Test windows : "+isWindows()+" // test keystore : "+type.equals("Keystore_Windows"));
if(isWindows() && type.equals("Keystore_Windows")){
System.out.println("Passé windows");
ks=KeyStore.getInstance("Windows-MY");
ks.load(null,null);
keystoreloaded=true;
}if(isMacOs()){
ks=KeyStore.getInstance("KeychainStore");
ks.load(null,null);
keystoreloaded=true;
}if((isWindows() && type.equals("Keystore_logiciel")) || isLinux()){
test();
char[] passwd=null;
JFileChooser keystorechooser = new JFileChooser();
keystorechooser.removeChoosableFileFilter(keystorechooser.getAcceptAllFileFilter());
keystorechooser.setDialogTitle("Ouverture du certificat");
keystorechooser.setFileFilter(new FileFilter() {

            @Override
            public String getDescription() {
                return ".p12, .jks";
            }

            @Override
            public boolean accept(File f) {
                if (f.isDirectory()) {
                    return true;
                } else {
                    String filename = f.getName().toUpperCase();
                    return filename.endsWith(".PFX") || filename.endsWith(".P12") || filename.endsWith(".JKS");
                }
            }
        });
if(keystorechooser.showOpenDialog(null)==JFileChooser.APPROVE_OPTION){
File fileselected=keystorechooser.getSelectedFile();
if(fileselected.getName().toUpperCase().endsWith("JKS")){
           ks = KeyStore.getInstance("JKS");
           typekeystore="JKS";
           
}else{
   ks = KeyStore.getInstance("PKCS12");
       typekeystore="P12";
       passwd = getPassword(keystorechooser.getSelectedFile().getName());
}
        InputStream is = new FileInputStream(fileselected);
        System.out.println("Keystore utilisé : "+fileselected.getName());
        if(!getKeystoreAnnule())
         ks.load(is, passwd);
        else
         ks=null;
        is.close();
here i get my pass of keystore if(isWindows() && Type.equals("Keystore_Windows")){
pass="".toCharArray();
}else{
JPasswordField Field = new JPasswordField();
if (JOptionPane.OK_OPTION == JOptionPane.showOptionDialog(null,
            Field, "Pass phrase : "+file, JOptionPane.OK_CANCEL_OPTION,
            JOptionPane.QUESTION_MESSAGE, null, null, null)) {
        pass = Field.getPassword();
    }
here i get my alias
Vector<String> vect=new Vector<String>();
String alias="";
Enumeration<String> enumalias = ks.aliases();    for (; enumalias.hasMoreElements(); ) {
        alias = (String)enumalias.nextElement();
        if (ks.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
         System.out.println("Certificat Alias:"+alias);
                vect.add(alias);    }
}
    if(typekeystore=="P12")
          Alias=alias;
    if(typekeystore=="JKS" || type.equals("Keystore_Windows"))
       Alias=choix(vect);
=====
the function choix:
String[] elements=new String[vect.size()];
for(int i=0;i<vect.size();i++)
elements[i]=vect.elementAt(i);
String s=null;
s = (String)JOptionPane.showInputDialog(
    null,
    "Choisir l'Alias du certificat",
    "Keystore",
    JOptionPane.QUESTION_MESSAGE,
    null,
    elements, // les possibilités 
    1);
return s;
=============
here is the cod to establish the connection:
               downloadFileUrl="https://.....";
Protocol myhttps = new Protocol("https", new AuthSSLProtocolSocketFactory(ks,alias,pass), 443);

Protocol.registerProtocol("https", myhttps); 
HttpClient client = new HttpClient();
GetMethod get=new GetMethod(downloadFileUrl);
client.executeMethod(get);
=====

解决方案 »

  1.   


    and of course, the AuthSSLProtocolSocketFactory
    public class AuthSSLProtocolSocketFactory implements SecureProtocolSocketFactory {
        private static final Log LOG = LogFactory.getLog(AuthSSLProtocolSocketFactory.class);    private SSLContext sslcontext = null;
        
        private KeyStore _ks;
        private String _alias;
        private String _password;
        public AuthSSLProtocolSocketFactory(KeyStore ks, String alias, String password)
        {
        super();
            _ks = ks;
            _alias = alias;
            _password = password;
        }
        
        /*
         *
         */
        
        private KeyManager[] createKeyManagers()throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException
        {
                KeyManager[] managers;
                if (_alias != null) {
                    managers = new KeyManager[] { new AliasKeyManager(_ks, _alias, _password) };
                } else {
                    // create a KeyManagerFactory from the keystore
                    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
                    kmf.init(_ks, _password == null ? null : _password.toCharArray());
                    managers = kmf.getKeyManagers();
                }
              return managers;
     }
            private TrustManager[] createTrustAllManagers(){
        
          TrustManager[] trustAllCerts = new TrustManager[] {
                     new X509TrustManager() {
                         public java.security.cert.X509Certificate[] getAcceptedIssuers(){
                             return null;
                         }
                         public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
                         public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
                     }
                 };
          
         return trustAllCerts;
        }
       
    private SSLContext createSSLContext() 
    {
        try 
        {  
         KeyManager[] managers;           managers=createKeyManagers();
         SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(managers,createTrustAllManagers(), new java.security.SecureRandom());
                return sc;

        } catch (NoSuchAlgorithmException e) {
        LOG.error(e.getMessage(), e);
        throw new AuthSSLInitializationError("Unsupported algorithm exception: " + e.getMessage());
        } catch (KeyStoreException e) {
        LOG.error(e.getMessage(), e);
        throw new AuthSSLInitializationError("Keystore exception: " + e.getMessage());
        } catch (GeneralSecurityException e) {
        LOG.error(e.getMessage(), e);
        throw new AuthSSLInitializationError("Key management exception: " + e.getMessage());
        }
        }
        private SSLContext getSSLContext() {
        if (this.sslcontext == null) {
         this.sslcontext = createSSLContext();
        }
        return this.sslcontext;
        }
        /**
        * Attempts to get a new socket connection to the given host within the given time limit.
        * <p>
        * To circumvent the limitations of older JREs that do not support connect timeout a
        * controller thread is executed. The controller thread attempts to create a new socket
        * within the given limit of time. If socket constructor does not return until the
        * timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
        * </p>
        *
        * @param host the host name/IP
        * @param port the port on the host
        * @param clientHost the local host name/IP to bind the socket to
        * @param clientPort the port on the local machine
        * @param params {@link HttpConnectionParams Http connection parameters}
        *
        * @return Socket a new socket
        *
        * @throws IOException if an I/O error occurs while creating the socket
        * @throws UnknownHostException if the IP address of the host cannot be
        * determined
        */
        public Socket createSocket(
        final String host,
        final int port,
        final InetAddress localAddress,
        final int localPort,
        final HttpConnectionParams params
        ) throws IOException, UnknownHostException, ConnectTimeoutException 
        {
        if (params == null) {
         throw new IllegalArgumentException("Parameters may not be null");
        }
        int timeout = params.getConnectionTimeout();
        SocketFactory socketfactory = getSSLContext().getSocketFactory();
        if (timeout == 0) {
         return socketfactory.createSocket(host, port, localAddress, localPort);
        } else {
        Socket socket = socketfactory.createSocket();
        SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
        SocketAddress remoteaddr = new InetSocketAddress(host, port);
        socket.bind(localaddr);
        socket.connect(remoteaddr, timeout);
        return socket;
        }
        }
        /**
        * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
        */
        public Socket createSocket( 
        String host,
        int port,
        InetAddress clientHost,
        int clientPort)
        throws IOException, UnknownHostException
        {
        return getSSLContext().getSocketFactory().createSocket(host,port,clientHost, clientPort);
        }
        /**
        * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
        */
        public Socket createSocket(String host, int port)
        throws IOException, UnknownHostException
        {
        return getSSLContext().getSocketFactory().createSocket(host,port);
        }
        /**
        * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
        */
        public Socket createSocket(Socket socket,String host,int port, boolean autoClose)
        throws IOException, UnknownHostException
        {
         return getSSLContext().getSocketFactory().createSocket( socket,host,port,autoClose);
        }

    ==================
    i trust all server certificate, and i give my keytsore; alias and password to establish the connection
      

  2.   

    这个问题困扰我2个星期了,只要我用pkcs12的keystore,或者是jks的都没有问题,但是只要我用windows的keystore,就发生javax.net.ssl.SSLHandshakeException: Received fatal alert: decrypt_error 
      

  3.   

    唉,似乎这个程序太长了,来看的人不多啊,但是我这个程序还是实现了建立server和client 双向验证的https链接的,就是一个小问题,不能使用windows的内置keystore,要是有人做过应该不难解决的