對於IBM MQ 怎麼使用SSL來保護通道,請轉官網查看
官網鏈接地址:https://www.ibm.com/support/knowledgecenter/zh/SSFKSJ_8.0.0/com.ibm.mq.explorer.doc/e_ssl.htm
之前我開始處理的時候也是看了很多官網的文檔,還有想安裝了去測試的,直接到官網下載一個版本安裝就好,有30天的試用期,我也就是在那30天裏面,充分利用了。
下面我也只上部分代碼,因爲主要的還是要自己去實踐,去學習,去研究纔能有更大的收穫
1. spring.xml配置
<!-- mq連接工廠-->
<bean id="ibmJmsConnectionFactory" class="com.ibm.mq.jms.MQConnectionFactory">
<property name="hostName" value="${mq.host}" />
<property name="port" value="${mq.sever.port}" />
<property name="CCSID" value="${mq.ccsid}" />
<property name="queueManager" value="${mq.sever.manageName}" />
<property name="channel" value="${mq.sever.channelName}" />
<property name="SSLFipsRequired" value="${ssl.fipsRequired}"/>
<property name="SSLPeerName" value="${ssl.server.sslPeerName}"/>
<!-- 設置SSL雙向加密通信 -->
<property name="SSLSocketFactory">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<!-- targetObject確定目標Bean,指定調用哪個Bean -->
<property name="targetObject" ref="sslContextFactory"></property>
<!-- targetMethod確定目標方法,指定調用目標Bean的哪個方法 -->
<property name="targetMethod" value="getSSLSocketFactory"></property>
</bean>
</property>
<property name="SSLCipherSuite" value="${ssl.cipherSuite}"/>
</bean>
2. sslContextFactory
/**
* @ClassName: SSLContextFactory
* @Description: 創建SSL雙向連接
* @author kz
* @date Jul 11, 2018 11:20:17 AM
*
*/
public class SSLContextFactory {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* @Fields ctx : 安全套接字協議 SSLSocketFactory、SSLServerSocketFactory和SSLEngine的工廠
*/
private SSLContext ctx = null;
/**
* @Fields protocal : 安全傳輸協議
*/
@Value("${ssl.protocal}")
private String protocal;
/**
* @Fields algorithm :ibm jdk 加密算法
*/
@Value("${ssl.algorithm}")
private String algorithm;
/**
* @Fields keyStoreType : 密鑰庫類型
*/
@Value("${ssl.keyStoreType}")
private String keyStoreType;
/**
* @Fields keyStorePassword : 密鑰庫密碼
*/
@Value("${ssl.keyStore.password}")
private String keyStorePassword;
/**
* @Fields sslSocketFactory : SSLSocket的工廠
*/
private SSLSocketFactory sslSocketFactory = null;
/**
* @Fields privateKeyPath : 私鑰文件路徑
*/
@Value("${ssl.privateKey.path}")
private String privateKeyPath;
/**
* @Fields publicKeyPath : 公鑰文件路徑
*/
@Value("${ssl.publicKey.path}")
private String publicKeyPath;
public SSLSocketFactory getSSLSocketFactory() {
try {
//獲取SSLContext的實例
ctx = SSLContext.getInstance(protocal);
SSLContext.setDefault(ctx);
//JSSE密鑰管理器
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
//信任管理器
TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
//密鑰存儲密鑰庫
KeyStore ks = KeyStore.getInstance(keyStoreType);
//信任密鑰存儲密鑰庫
KeyStore tks = KeyStore.getInstance(keyStoreType);
//加載客戶端私鑰文件 使用私鑰加密
ks.load(new FileInputStream(CommonUtils.getClassLoadPath()+privateKeyPath), keyStorePassword.toCharArray());
//加載公鑰文件 使用公鑰文件解密
tks.load(new FileInputStream(CommonUtils.getClassLoadPath()+publicKeyPath), keyStorePassword.toCharArray());
kmf.init(ks, keyStorePassword.toCharArray());
tmf.init(tks);
TrustManager[] tm = tmf.getTrustManagers();
//X509TrustManager爲TrustManager的子接口,管理X509證書,驗證遠程安全套接字
final X509TrustManager[] x509tm = Arrays.asList(tm).toArray(new X509TrustManager[tm.length]);
X509TrustManager[] x509tmArray = new X509TrustManager[] {
new X509TrustManager() {
/* (non Javadoc)
* @Title: getAcceptedIssuers
* @Description: 返回受身份驗證同位體信任的認證中心的數組
* @return
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/
@Override
public X509Certificate[] getAcceptedIssuers() {
return x509tm[0].getAcceptedIssuers();
}
/* (non Javadoc)
* @Title: checkClientTrusted
* @Description: 給出同位體提供的部分或完整的證書鏈,構建到可任的根的證書路徑,並且返回是否可以確認和信任將其用於基於身份驗證類型的客戶端 SSL 身份驗證
* @param chain
* @param authType
* @throws CertificateException
* @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String)
*/
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType){
for(int i=0;i<chain.length;i++) {
logger.info("-->>Check client cert"+i+"/"+authType+"<<--");
}
try {
x509tm[0].checkClientTrusted(chain, authType);
} catch (CertificateException e) {
logger.error("Check client Cert Exception:"+e.getMessage(),e);
}
}
/* (non Javadoc)
* @Title: checkServerTrusted
* @Description: 給出同位體提供的部分或完整的證書鏈,構建到可任的根的證書路徑,並且返回是否可以確認和信任將其用於基於身份驗證類型的服務器 SSL 身份驗證
* @param chain 證書鏈
* @param authType 使用的密鑰交換算法 RSAwith256
* @throws CertificateException 此證書鏈不受trustManager信任
* @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String)
*/
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType){
for(int i=0;i<chain.length;i++) {
logger.info("-->>Check server cert"+i+"/"+authType+"<<--");
}
try {
x509tm[0].checkServerTrusted(chain, authType);
logger.info("finish check server cert");
} catch (CertificateException e) {
logger.error("Check server Cert Exception:"+e.getMessage(),e);
e.printStackTrace();
}
}
}
};
//初始化實例
ctx.init(kmf.getKeyManagers(), x509tmArray, null);
// SSLEngine en = ctx.createSSLEngine();
//返回支持的加密套件
// logger.info("Support CipherSuites:"+Arrays.asList(en.getSupportedCipherSuites()));
//返回啓用的加密套件
// logger.info("Used CipherSuites:"+Arrays.asList(en.getEnabledCipherSuites()));
} catch (Exception e) {
e.printStackTrace();
logger.error("create ssl connection failure:"+e.getMessage(),e);
}
sslSocketFactory = ctx.getSocketFactory();
return sslSocketFactory;
}
}
3. properties配置文件中的配置信息
#ssl 安全傳輸協議
ssl.protocal=TLSv1.2
#ssl 加密套件
ssl.cipherSuite=SSL_RSA_WITH_AES_256_CBC_SHA256
#從對等隊列管理器檢查證書的專有名稱
ssl.server1.sslPeerName=這裏就不貼出具體值了
#ssl 加密算法
ssl.algorithm=IBMX509
#ssl 密鑰庫類型
ssl.keyStoreType=PKCS12
#ssl 密鑰庫密碼
ssl.keyStore.password=這裏就不貼出具體值了
ssl.fipsRequired=true
#私鑰jks密鑰文件路徑
ssl.privateKey.path=這裏就不貼出具體值了
#公鑰jks密鑰文件路徑
ssl.publicKey.path=這裏就不貼出具體值了
關於 fipsRequired的設置,請參考官網給出的說明