近期客户为满足安全要求,提了让业务应用使用 SSL 方式连接 SAP HANA 数据库的需求。本人查询 SAP官方文档 发现数据库支持 SSL 连接,有参数直接加到 JDBC 的 URL 后边就行了,为了便于验证写了个 JDBC 的 demo,在此处记录一二。

准备工作

JdbcTest.java

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;public class JdbcTest {public static Connection getConnection() throws FileNotFoundException, IOException {Connection conn = null;Properties prop = new Properties();try {InputStream in = JdbcTest.class.getResourceAsStream("jdbc.properties");prop.load(in);Class.forName(prop.getProperty("jdbcDriver"));//@formatter:offconn = (Connection) DriverManager.getConnection(prop.getProperty("jdbcUrl"), prop.getProperty("username"),prop.getProperty("password"));//@formatter:on} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();}return conn;}public static void releaseConnection(Connection conn) {try {if (conn != null) {conn.close();System.out.println("Connection has closed");}} catch (SQLException e) {e.printStackTrace();}}public static void main(String[] args) throws FileNotFoundException, IOException {Connection conn = getConnection();if (conn != null)System.out.println("Connection has establish");releaseConnection(conn);}
}

jdbc.properties

jdbcDriver=com.sap.db.jdbc.Driver
jdbcUrl=jdbc:sap://10.2.42.15:30015/?databaseName=Q15&encrypt=true&trustStore=/deployments/SSL/jssecacerts&trustStorePassword=changeit
username=test
password=ABCabc123

InstallCert.java

/** 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.*/
/*** Originally from:* 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 <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() {/** * This change has been done due to the following resolution advised for Java 1.7+http://infposs.blogspot.kr/2013/06/installcert-and-java-7.html**/ return new X509Certificate[0]; //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);}}
}

将这三个文件和 ngdbc-2.4.70.jar 上传到服务器目录 /deployments/SSL,执行编译命令:

cd /deployments/SSL
javac JdbcTest.java
javac InstallCert.java

此时目录中会有三个class文件(有个内部类):

$ ls
InstallCert.class  InstallCert$SavingTrustManager.class  JdbcTest.class  ngdbc-2.4.70.jar
InstallCert.java   jdbc.properties                       JdbcTest.java

导入证书

执行 java InstallCert <域名 或 IP>[:端口号],根据提示输入 1 导入证书,公钥证书文件是从数据库端返回的,会被工具类转换成 Java 程序能识别的证书格式(JKS),输出证书到当前目录下的 jssecacerts,后边要做的就是在 JDBC 连接地址上添加这个证书的绝对位置,使用证书加密连接数据库。

SAP 技术支持人员提供的证书有问题,hostname 与 证书里签得不一样,导致他们给的 cer 证书导入系统后报错如下:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

引起这个报错的原因不大好定位,使用 InstallCert.java 导入证书时会很清晰地提示证书有问题,而且也不需要额外上传 cer 证书 再执行 keytool 导入证书命令。

验证连接

修改 jdbc.properties,执行 java -cp ".:ngdbc-2.4.70.jar" JdbcTest,当出现如下输出而不是报错即连接测试通过。

$ java JdbcTest
Connection has establish
Connection has closed

参考资料:

  • https://help.sap.com/viewer/102d9916bf77407ea3942fef93a47da8/1.0.11/en-US/2624cb2191be4f68897b91023ab41d0c.html
  • https://www.cnblogs.com/javadeveloper/p/6120041.html
  • https://blog.csdn.net/qq_31222053/article/details/94174506

使用 SSL 加密的 JDBC 连接 SAP HANA 数据库相关推荐

  1. 使用ABAP(ADBC)和Java(JDBC)连接SAP HANA数据库

    在表DBCON里维护一条记录,指向HANA数据库.con_ENV里填入HANA数据库的主机名和端口号.如vmXXXX:30015 DATA: ls_new TYPE DBCON.ls_new-con_ ...

  2. 使用ABAP(ADBC)和Java(JDBC)连接SAP HANA数据库 1

    在表DBCON里维护一条记录,指向HANA数据库.con_ENV里填入HANA数据库的主机名和端口号.如vmXXXX:30015 DATA: ls_new TYPE DBCON.ls_new-con_ ...

  3. 【FineReport】帆软报表平台的安装与连接 SAP HANA 数据库

    [FineReport]帆软报表平台的安装与连接 SAP HANA 数据库 1.下载帆软 2.安装软件 3.连接HANA 4.访问数据 1.下载帆软 (1)帆软最新版本软件下载地址:https://w ...

  4. FineReport 连接 SAP HANA 数据库

    FineReport 连接 SAP HANA 数据库 文章目录 FineReport 连接 SAP HANA 数据库 一.拷贝jar包到FR工程 二.设计器中定义数据连接 1.JDBC方式连接 2.X ...

  5. python获取sap数据_python 连接 SAP HANA 数据库

    SAP HANA 是SAP 新的内存数据库: 目前学习python数据处理分析,现在想要连接 SAP HANA 数据库, 发现目前python已经发布了连接 SAP HANA的库 pyhddb 1.需 ...

  6. Kettle (3) - 连接 SAP Hana 数据库

    PDI 7.1 在数据库连接中,没有提供 SAP Hana 数据库的连接选项.需要先在操作系统中安装 SAP Hana Client,然后将驱动程序拷贝到 PDI安装目录/data-integrati ...

  7. Java 连接SAP Hana数据库

    最近项目有用到hana数据库的,记录一下相关资料. hana连接可参考官网:Hana JDBC创建 整个步骤如下: 项目中增加ngdbc.jar,可以从该博客中链接下载com.sap.db.jdbc. ...

  8. Kettle连接 SAP Hana 数据库

    看这篇 https://blog.csdn.net/stone0823/article/details/78629096 如果要下载SAP Hana Client 点这里 https://tools. ...

  9. Python连接SAP HANA数据库插入数据

    工作的时候需要往HANA数据库插入一些测试数据,我使用的连接HANA的工具DBeaver又不能像Mysql那样批量执行多条插入语句,就想用python连接HANA往里循环插入数据,由于代码水平有限,尝 ...

最新文章

  1. 吴文俊人工智能科学技术奖:陆汝钤院士、百度王海峰等获奖
  2. fork/join 全面剖析,你可以不用,但是不能不懂!
  3. 【数据结构与算法-2】链表
  4. MYSQL视图用户管理
  5. 四针角oled屏连接arduino_使用Arduino开发板连接OLED显示屏制作一款智能手表
  6. LeetCode371——Sum of Two Integers(不用+)
  7. 最新dotCMS SQL注入漏洞 攻击者可获得敏感数据 绿盟科技发布安全威胁通告
  8. (转)谷歌安卓官方教程中文版
  9. linux sort排序字符串位数,Linux sort命令详解:字符串排序
  10. 计算机中心机房设计规范,GB50174-2017 数据中心机房设计规范
  11. Ubuntu18.04 下的Gif录制工具
  12. 12月Java原生商城APP源码-完全开源
  13. 方舟原始恐惧mod生物代码_方舟MOD
  14. python实现杨辉三角
  15. 外螺纹对照表_美制螺纹内外径对照表unf
  16. 现代JS名词概念系列——函数的纯洁性【龟速翻译】
  17. XML配置文件的读取
  18. Boardcast03
  19. DbVisualizer 10破解之后,在输入框使用光标无法准确定位字符
  20. 基于Android的健康宝体检app介绍(一)

热门文章

  1. 【嵌入式--伺服电机】直流有刷电机工作原理
  2. Css选择器种类以及优先级
  3. python计算均方误差_在python中寻找线性回归的均方误差(使用scikit learn)
  4. linux kernel fuzzing test - 概述
  5. 解决 ubuntu 16.04安装软件遇到的一个罕见巨坑
  6. Android中动画详细讲解
  7. 两台电脑传文件|如何快速传输几百G的文件
  8. 【高等数学】多元函数积分的轮换性,轮换对称性,对称性的区别
  9. 【C语言】解一元二次方程(包含虚部)
  10. 密码学和安全问题讨论大集合