通过Java访问国内Azure服务
来源:互联网 发布:淘宝卖高仿耐克鞋 编辑:程序博客网 时间:2024/04/28 12:58
随着Azure服务在国内的开展,不少Java用户也开始在国内Azure部署应用。不过,目前有一个问题,是关于证书。国内Azure服务HTTPS端点的证书,是由CNNIC颁发的,而CNNIC作为一个根证书颁发机构,不被Oracle JDK信任。如果通过Oracle JDK开发一个应用,要去访问国内Azure的各种HTTPS地址,比如管理API、Service Bus、存储URL、SQL数据库等等,都会遇到类似下面的问题
Dec 13, 2013 8:35:57 PM com.microsoft.sqlserver.jdbc.TDSChannel enableSSLINFO: java.security path: C:\Program Files\Java\jre6\lib\securitySecurity providers: [SUN version 1.6, SunRsaSign version 1.5, SunJSSE version 1.6, SunJCE version 1.6, SunJGSS version 1.0, SunSASL version 1.5, XMLDSig version 1.0, SunPCSC version 1.6]SSLContext provider info: Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)SSLContext provider services:[SunJSSE: KeyFactory.RSA -> sun.security.rsa.RSAKeyFactory
.......
TrustManagerFactory provider info: Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)TrustManagerFactory default algorithm: PKIXjava.ext.dirs: C:\Program Files\Java\jre6\lib\ext;C:\WINDOWS\Sun\Java\lib\extcom.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target". ClientConnectionId:4b1a3848-7aa5-4474-b7fc-25f79f52b4de
报错的原因,是JDK不信任服务端的HTTPS证书。
要解决这个问题,有几个办法:
1. 如果是Linux客户端,可以试试用OpenJDK http://openjdk.java.net/
2. 如果不要求数据加密,可以连接HTTP或普通端点,比如存储
3. 如果连接对象是SQL数据库,可以禁用加密(在连接字符串中将encrypt去掉)
4. 可以写一个小程序,下载服务端证书,然后导入本地JDK的信任证书列表 (对SQL数据库无效,因为不是HTTPS端点)
package example;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.security.KeyStore;import java.security.MessageDigest;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLException;import javax.net.ssl.SSLSocket;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManager;import javax.net.ssl.TrustManagerFactory;import javax.net.ssl.X509TrustManager;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 <host>[: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);}}}
0 0
- 通过Java访问国内Azure服务
- Python应用访问国内Azure站点
- 通过 Azure 媒体服务进行高速编码
- 通过Microsoft Azure服务设计网络架构的经验分享
- PHP应用访问Azure中国区存储服务
- 有谁知道ios如何访问Azure的相关服务?
- 通过NFS服务共享访问
- 在国内Windows Azure网站服务上一键发布Wordpress, phpBB, joomla等应用
- 通过java访问HDFS
- Java访问远程服务
- Windows Azure真实案例--Lokad 公司通过软件+服务高效提供先进的预测服务
- 通过Spring进行远程服务访问
- 通过编程访问Google账户和服务
- Silverlight通过ISA访问WCF服务
- 通过Spring进行远程服务访问
- 通过hosts设置访问Google服务
- 通过 Apache 代理访问 NodeJS 服务
- 云服务通过nginx访问静态资源
- 今天开始
- Resource '/servers' does not exist 问题的解决
- 反反复的
- maven聚合和继承
- 二分查找(Binary Search) 常见问题解决方法总结
- 通过Java访问国内Azure服务
- 虚拟化-可虚拟化条件
- 考核的时间间隔思考
- vs2012 mfc 右键快捷菜单
- Fix协议介绍21-party信息查询(PartyEntitlementsRequest )
- mysql练习之Alter用法总结
- Gartner总结2014年十大科技趋势
- QQ彩票快3返还概率分析
- Fix协议介绍22-party信息查询报告(PartyEntitlementsReport)