javax.net.ssl.SSLException: java.lang.UnsupportedOperationException at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1844) at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1827) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1346) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) at org.vangen.auth.InstallCert.main(InstallCert.java:81)Caused by: java.lang.UnsupportedOperationException at org.vangen.auth.InstallCert$SavingTrustManager.getAcceptedIssuers(InstallCert.java:168) at sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(SSLContextImpl.java:926) at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:872) at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:814) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) ... 2 moreTo avoid this error, you will need to change how accepted issuers are returned. The original code threw an exception for this method. The Java 7 implementation calls this method, which was not the case with earlier versions of Java. The solution to this problem is to simply return an empty array like this:
@Override publicX509Certificate[] getAcceptedIssuers() { returnnewX509Certificate[0]; // throw new UnsupportedOperationException(); } |
packageorg.vangen.auth; importjava.io.BufferedReader;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;importjava.security.KeyStore;importjava.security.MessageDigest;importjava.security.cert.CertificateException;importjava.security.cert.X509Certificate; importjavax.net.ssl.SSLContext;importjavax.net.ssl.SSLException;importjavax.net.ssl.SSLSocket;importjavax.net.ssl.SSLSocketFactory;importjavax.net.ssl.TrustManager;importjavax.net.ssl.TrustManagerFactory;importjavax.net.ssl.X509TrustManager; publicclassInstallCert { publicstaticvoidmain(finalString[] args)throwsException { String host; intport; char[] passphrase; if((args.length ==1) || (args.length ==2)) { finalString[] c = args[0].split(":"); host = c[0]; port = (c.length ==1) ?443: Integer.parseInt(c[1]); finalString p = (args.length ==1) ?"changeit": args[1]; passphrase = p.toCharArray(); }else{ System.out.println( "Usage: java InstallCert[:port] [passphrase]"); return; } File file =newFile("jssecacerts"); if(file.isFile() ==false) { finalcharSEP = File.separatorChar; finalFile dir =newFile(System.getProperty("java.home") + SEP +"lib"+ SEP +"security"); file =newFile(dir,"jssecacerts"); if(file.isFile() ==false) { file =newFile(dir,"cacerts"); } } System.out.println("Loading KeyStore "+ file +"..."); finalInputStream in =newFileInputStream(file); finalKeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(in, passphrase); in.close(); finalSSLContext context = SSLContext.getInstance("TLS"); finalTrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory .getDefaultAlgorithm()); tmf.init(ks); finalX509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; finalSavingTrustManager tm =newSavingTrustManager( defaultTrustManager); context.init(null,newTrustManager[] { tm },null); finalSSLSocketFactory factory = context.getSocketFactory(); System.out.println("Opening connection to " + host +":"+ port +"..."); finalSSLSocket socket = (SSLSocket) factory.createSocket(host, port); socket.setSoTimeout(10000); try{ System.out.println("Starting SSL handshake..."); socket.startHandshake(); socket.close(); System.out.println(); System.out.println("No errors, certificate is already trusted"); }catch(finalSSLException e) { System.out.println(); e.printStackTrace(System.out); } finalX509Certificate[] chain = tm.chain; if(chain ==null) { System.out.println("Could not obtain server certificate chain"); return; } finalBufferedReader reader = newBufferedReader(newInputStreamReader(System.in)); System.out.println(); System.out.println("Server sent "+ chain.length +" certificate(s):"); System.out.println(); finalMessageDigest sha1 = MessageDigest.getInstance("SHA1"); finalMessageDigest md5 = MessageDigest.getInstance("MD5"); for(inti =0; i < chain.length; i++) { finalX509Certificate cert = chain[i]; System.out.println(" "+ (i +1) +" Subject " + cert.getSubjectDN()); System.out.println(" Issuer "+ cert.getIssuerDN()); sha1.update(cert.getEncoded()); System.out.println(" sha1 "+ toHexString(sha1.digest())); md5.update(cert.getEncoded()); System.out.println(" md5 "+ toHexString(md5.digest())); System.out.println(); } System.out.println("Enter certificate to add to trusted keystore" +" or 'q' to quit: [1]"); finalString line = reader.readLine().trim(); intk; try{ k = (line.length() ==0) ?0: Integer.parseInt(line) -1; }catch(finalNumberFormatException e) { System.out.println("KeyStore not changed"); return; } finalX509Certificate cert = chain[k]; finalString alias = host +"-"+ (k +1); ks.setCertificateEntry(alias, cert); finalOutputStream out =newFileOutputStream(file); ks.store(out, passphrase); out.close(); System.out.println(); System.out.println(cert); System.out.println(); System.out.println( "Added certificate to keystore 'cacerts' using alias '" + alias +"'"); } privatestaticfinalchar[] HEXDIGITS ="0123456789abcdef".toCharArray(); privatestaticString toHexString(finalbyte[] bytes) { finalStringBuilder sb =newStringBuilder(bytes.length *3); for(intb : bytes) { b &=0xff; sb.append(HEXDIGITS[b >>4]); sb.append(HEXDIGITS[b &15]); sb.append(' '); } returnsb.toString(); } privatestaticclassSavingTrustManagerimplementsX509TrustManager { privatefinalX509TrustManager tm; privateX509Certificate[] chain; SavingTrustManager(finalX509TrustManager tm) { this.tm = tm; } @Override publicX509Certificate[] getAcceptedIssuers() { returnnewX509Certificate[0]; // throw new UnsupportedOperationException(); } @Override publicvoidcheckClientTrusted(finalX509Certificate[] chain, finalString authType) throwsCertificateException { thrownewUnsupportedOperationException(); } @Override publicvoidcheckServerTrusted(finalX509Certificate[] chain, finalString authType) throwsCertificateException { this.chain = chain; this.tm.checkServerTrusted(chain, authType); } }}
以下是原版for JDK5 and JDK6的,从google code搜索而来
package com.aw.ad.util;/* * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//** * http://blogs.sun.com/andreas/resource/InstallCert.java * Use: * java InstallCert hostname * Example: *% java InstallCert ecc.fedora.redhat.com */import javax.net.ssl.*;import java.io.*;import java.security.KeyStore;import java.security.MessageDigest;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;/** * Class used to add the server's certificate to the KeyStore * with your trusted certificates. */public class InstallCert { public static void main(String[] args) throws Exception { String host; int port; char[] passphrase; if ((args.length == 1) || (args.length == 2)) { String[] c = args[0].split(":"); host = c[0]; port = (c.length == 1) ? 443 : Integer.parseInt(c[1]); String p = (args.length == 1) ? "changeit" : args[1]; passphrase = p.toCharArray(); } else { System.out.println("Usage: java InstallCert[:port] [passphrase]"); return; } File file = new File("jssecacerts"); if (file.isFile() == false) { char SEP = File.separatorChar; File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security"); file = new File(dir, "jssecacerts"); if (file.isFile() == false) { file = new File(dir, "cacerts"); } } System.out.println("Loading KeyStore " + file + "..."); InputStream in = new FileInputStream(file); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(in, passphrase); in.close(); SSLContext context = SSLContext.getInstance("TLS"); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; SavingTrustManager tm = new SavingTrustManager(defaultTrustManager); context.init(null, new TrustManager[]{tm}, null); SSLSocketFactory factory = context.getSocketFactory(); System.out.println("Opening connection to " + host + ":" + port + "..."); SSLSocket socket = (SSLSocket) factory.createSocket(host, port); socket.setSoTimeout(10000); try { System.out.println("Starting SSL handshake..."); socket.startHandshake(); socket.close(); System.out.println(); System.out.println("No errors, certificate is already trusted"); } catch (SSLException e) { System.out.println(); e.printStackTrace(System.out); } X509Certificate[] chain = tm.chain; if (chain == null) { System.out.println("Could not obtain server certificate chain"); return; } BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); System.out.println(); System.out.println("Server sent " + chain.length + " certificate(s):"); System.out.println(); MessageDigest sha1 = MessageDigest.getInstance("SHA1"); MessageDigest md5 = MessageDigest.getInstance("MD5"); for (int i = 0; i < chain.length; i++) { X509Certificate cert = chain[i]; System.out.println (" " + (i + 1) + " Subject " + cert.getSubjectDN()); System.out.println(" Issuer " + cert.getIssuerDN()); sha1.update(cert.getEncoded()); System.out.println(" sha1 " + toHexString(sha1.digest())); md5.update(cert.getEncoded()); System.out.println(" md5 " + toHexString(md5.digest())); System.out.println(); } System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]"); String line = reader.readLine().trim(); int k; try { k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1; } catch (NumberFormatException e) { System.out.println("KeyStore not changed"); return; } X509Certificate cert = chain[k]; String alias = host + "-" + (k + 1); ks.setCertificateEntry(alias, cert); OutputStream out = new FileOutputStream("jssecacerts"); ks.store(out, passphrase); out.close(); System.out.println(); System.out.println(cert); System.out.println(); System.out.println ("Added certificate to keystore 'jssecacerts' using alias '" + alias + "'"); } private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); private static String toHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 3); for (int b : bytes) { b &= 0xff; sb.append(HEXDIGITS[b >> 4]); sb.append(HEXDIGITS[b & 15]); sb.append(' '); } return sb.toString(); } private static class SavingTrustManager implements X509TrustManager { private final X509TrustManager tm; private X509Certificate[] chain; SavingTrustManager(X509TrustManager tm) { this.tm = tm; } public X509Certificate[] getAcceptedIssuers() { throw new UnsupportedOperationException(); } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { throw new UnsupportedOperationException(); } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { this.chain = chain; tm.checkServerTrusted(chain, authType); } }}