package com.neohope.utils;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class NDigest
{
/**
* Bytes to Hex String
*
* @param hexBytes
*
* @return hex string
*/
private static String bytesToHexString(byte[] hexBytes)
{
StringBuffer buf = new StringBuffer();
for (int i = 0; i < hexBytes.length; i++)
{
if ((hexBytes[i] & 0xff) < 0x10)
{
buf.append("0");
}
buf.append(Long.toString(hexBytes[i] & 0xff, 16));
}
return buf.toString();
}
/**
* calc MD5 for string
*
* @param textIn
*
* @return md5 digest string
* @throws NoSuchAlgorithmException
*/
public static String MD5Digest(String textIn)
throws NoSuchAlgorithmException
{
byte[] textData = textIn.getBytes();
MessageDigest md = null;
md = MessageDigest.getInstance("MD5");
md.reset();
md.update(textData);
byte[] encodedData = md.digest();
return bytesToHexString(encodedData);
}
/**
* calc SHA1 for string
*
* @param textIn
*
* @return sha1 digest string
* @throws NoSuchAlgorithmException
*/
public static String SHA1Digest(String textIn)
throws NoSuchAlgorithmException
{
byte[] textData = textIn.getBytes();
MessageDigest md = null;
md = MessageDigest.getInstance("SHA1");
md.reset();
md.update(textData);
byte[] encodedData = md.digest();
return bytesToHexString(encodedData);
}
/**
* Encode a string using Base64 encoding.
*
* @param textIn
* @return String
*/
public static String base64Encode(String textIn)
{
sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
return encoder.encodeBuffer(textIn.getBytes()).trim();
}
/**
* Decode a string using Base64 encoding.
*
* @param textIn
* @return String
* @throws IOException
*/
public static String decodeString(String textIn) throws IOException
{
sun.misc.BASE64Decoder dec = new sun.misc.BASE64Decoder();
return new String(dec.decodeBuffer(textIn));
}
/**
* 使用 HMAC-SHA-1 签名方法对对textIn进行摘要
*
* @param textIn
* @param keyIn
* @return
* @throws Exception
*/
public static String HmacSHA1Digest(String textIn, String keyIn)
throws Exception
{
final String MAC_NAME = "HmacSHA1";
final String ENCODING = "UTF-8";
byte[] keyData = keyIn.getBytes(ENCODING);
SecretKey secretKey = new SecretKeySpec(keyData, MAC_NAME);
Mac mac = Mac.getInstance(MAC_NAME);
mac.init(secretKey);
byte[] textData = textIn.getBytes(ENCODING);
byte[] encodedData = mac.doFinal(textData);
return bytesToHexString(encodedData);
}
// 我就是那个测试函数。。。
public static void main(String args[]) throws Exception
{
String key = "Y9zTQxRvxwrHOi45OoKNnIoxboerNqt3";
String text = "Good good study, day day up.";
String hmacSHA1 = HmacSHA1Digest(text, key );
String base64 = base64Encode(hmacSHA1);
System.out.println(hmacSHA1 );
System.out.println(cbase64);
}
}
Category Archives: DevOps
常用SSL证书格式及转换方法
一、证书相关文件类型说明
KEY
通常用来存放私钥(或公钥),可能是PEM或DER格式。私钥可以对证书/程序进行签名,也可以用解密公钥加密郭的HTTP消息,是一定要妥善保管的,是不能交给别人的。比如下面是一个典型的私钥:
-----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQC0oavm8KvMLbXqIPheGjeKJ5yCQ2DUBFjmcDuQzpZgHO+NC50f 9sMFZo/MO2HCvejIWHCzbxzFeGgNN/1IEH2oSbJdeAlXTpwNqBqwQBDj/5neM98E a6dvi+FF3loGhhodb0FvSC+TLldfGJodm+kveu3kkp6txeYjaIpcKBr2bwIDAQAB AoGBAJYs//WeTMcRjfgc90GNfHWRX07x49QB1UOpNey7xUwdYpCagkTr7NJVpeI/ 0JSPPbUrym90RrBq3d93mE3M4BqeODGoh2vy1/sArlwFut9SrNA/i7e7wikCQsLa eQRaiNRbDlooxb6J0LLS6M0bb8p/YivFBYIN5G2hs7bgJwCpAkEA63clQ7IQfhGw YuHSaW29GR4YV4MsAcqTQBpjIpQxtrCKCWJElE5Si0wyb48buMZlrhNRpc5Dz+FW HitDUwu2fQJBAMRiVreK4GX48O/f4+dSW8q/lbXQQp4vLB6KxjL+lqEgvzOMhEzJ 6z8BP52J2C3AS/Qen9cH+y0iD5atEYNI+FsCQQDjIUXX2/6erQ95Ap3Fxu4+OVJ/ r+8WN0L89bck1tBxii9Mx/ahHD/xUGniRKgX/4B7fvUmPCYbcyBv74l8pPK9AkAw PDsyb8D4KvH66RIQQjFblj0OYC3Mrqd2hP1zjwauYt2zqqLgPYQzgHoAltfrPN0r A86cwVAXYNNVXgL8LRMbAkEAm5kTm8CsNF4fAcAFFLZMHbz3vkidsnCvHiqXd9vq GCrms/STzQq3LVQqHll1g2SJAYy80SXPSoZVbCxA9pBgzw== -----END RSA PRIVATE KEY-----
查看私钥信息:
openssl rsa -in test.key -text -noout openssl rsa -in test.key -text -noout -inform der
CSR
证书签名请求,即Certificate Signing Request,可能是PEM或DER格式,是向权威证书颁发机构获得签名证书的申请,是一个用私钥签名的,包括了公钥+证书申请者信息的文件。比如下面是一个典型的CSR文件:
-----BEGIN CERTIFICATE REQUEST----- MIIBrzCCARgCAQAwbzELMAkGA1UEBhMCQ04xETAPBgNVBAgMCFNoYW5nSGFpMREw DwYDVQQHDAhTaGFuZ0hhaTEQMA4GA1UECgwHTkVPSE9QRTEUMBIGA1UECwwLRGV2 ZWxvcG1lbnQxEjAQBgNVBAMMCU5NeUNBMTAyNDCBnzANBgkqhkiG9w0BAQEFAAOB jQAwgYkCgYEAtKGr5vCrzC216iD4Xho3iiecgkNg1ARY5nA7kM6WYBzvjQudH/bD BWaPzDthwr3oyFhws28cxXhoDTf9SBB9qEmyXXgJV06cDagasEAQ4/+Z3jPfBGun b4vhRd5aBoYaHW9Bb0gvky5XXxiaHZvpL3rt5JKercXmI2iKXCga9m8CAwEAAaAA MA0GCSqGSIb3DQEBBQUAA4GBAA5BUPQcmpUVliu1DHqflVTXR7zOfhtd6UX1uU90 TEGAYlzaggU+dZRtXC86ha+MoiCX2598w4OaM/7vErSOUbwU3Nou9/ooyh+eLt8U ozwHAC6Xpw2phm9d/RkbTpGXCoCRFykV7K8OfS2BYgdQstOJWRti08VD/03NjESd wMIf -----END CERTIFICATE REQUEST-----
查看CSR信息:
openssl req -noout -text -in test.csr openssl req -noout -text -in test.csr -inform der
PEM
PEM证书,即Privacy Enhanced Mail,多用于linux服务器,是Base64编码的文本文件,可以用文本编辑器打开直接查看。PEM证书是互联网中最常使用的证书格式,可用于保存服务器证书、中级证书、私钥等。一个PEM文件中可以保持多个证书及私钥(但一般大家会把证书及私钥放到不同的PEM文件中)。PEM文件的常用后缀有:.pem、.crt、.cer、.key等。 。比如下面是一个典型的PEM文件:
-----BEGIN CERTIFICATE----- MIICrDCCAhWgAwIBAgIJAMUPP9qD0sTlMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV BAYTAkNOMREwDwYDVQQIDAhTaGFuZ0hhaTERMA8GA1UEBwwIU2hhbmdIYWkxEDAO BgNVBAoMB05FT0hPUEUxFDASBgNVBAsMC0RldmVsb3BtZW50MRIwEAYDVQQDDAlO TXlDQTEwMjQwHhcNMTYwMzI1MTM0MDI3WhcNMTkwMzI1MTM0MDI3WjBvMQswCQYD VQQGEwJDTjERMA8GA1UECAwIU2hhbmdIYWkxETAPBgNVBAcMCFNoYW5nSGFpMRAw DgYDVQQKDAdORU9IT1BFMRQwEgYDVQQLDAtEZXZlbG9wbWVudDESMBAGA1UEAwwJ Tk15Q0ExMDI0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0oavm8KvMLbXq IPheGjeKJ5yCQ2DUBFjmcDuQzpZgHO+NC50f9sMFZo/MO2HCvejIWHCzbxzFeGgN N/1IEH2oSbJdeAlXTpwNqBqwQBDj/5neM98Ea6dvi+FF3loGhhodb0FvSC+TLldf GJodm+kveu3kkp6txeYjaIpcKBr2bwIDAQABo1AwTjAdBgNVHQ4EFgQUMeG4c9MI Dl8jMTZ3w/V4fAYdNMgwHwYDVR0jBBgwFoAUMeG4c9MIDl8jMTZ3w/V4fAYdNMgw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCG6ROpwc+j9GoMk02YnRwb VlgYkMjtH2vIb/+zDYmgjOQL0uYJ2xt7LHf2zrRP053rgIJskznNn6CLrM85Dwb0 DqkgwccHYd2439hTZhdZ5BMe7FxUCfeZvKgJ7VjOf1aaBrdUfy5RgikfO6CX6v1L eaV1orOAEma0muLIyE9igQ== -----END CERTIFICATE-----
查看PEM信息:
openssl x509 -in test.pem -text -noout
DER
DER证书,即Distinguished Encoding Rules,多用于Windows服务器及Java平台,为二进制格式,不可以用文本编辑器打开直接查看。DER文件的常用后缀有:.der、.cer等。 所以当您拿到一个证书文件时,可以用文本工具打开看一下,如果可读,一般是PEM格式,如果是二进制文件,一般是DER格式。
查看DER信息:
openssl x509 -in test.der -inform der -text -noout
PKCS#7/P7B
PKCS#7/P7B证书是是Base64编码的文本文件, 证书以”—–BEGIN PKCS7—–“开始,以”—–END PKCS7—–“结束。PKCS#7/P7B证书的常用后缀名有.p7b、.p7c。 PKCS#7/P7B文件中只有证书及证书链,不会包含私钥。Windows及Tomcat都支持这种证书。
openssl pkcs7 -in test.p7b -noout
PKCS#12/P12/PFX
PKCS#12/P12/PFX证书是经过加密的二进制格式,可用于保存服务器证书、中级证书、私钥等。PKCS#12/P12/PFX证书的常用后缀名有 .pfx、.p12。PKCS#12/P12/PFX证书通常用于Windows平台上的证书及私钥的导入及导出。导入及导出时,需要输入PKCS#12/P12/PFX文件的秘密。
openssl pkcs12 -in test.p12 -noout
JKS
JKS,即Java Key Storage,是JAVA程序最常用的证书存储方式。JKS按使用方式,一般会人为的区分为CASTORE,KEYSTORE和TRUSTSTORE,其中CASTORE是JDK/JRE环境自带的,用于存储JAVA信任的CA证书,通常是%JAVA_HOME%/lib/security/cacerts这个文件,相当于一个专门用于存储CA证书的全局TRUSTSTORE;KEYSTORE用于存储私钥,在通讯过程中进行解密,或则用于进行签名;TRUSTSTORE存放的是可以信任的证书,如果是自签名证书的话,建议CASTORE中也事先导入会好一些,会避免很多问题。
查看JKS文件:
keytool -list -v -keystore test.jks -storepass password
总结
其实,咱们总结一下:
1、KEY一般为私钥
2、CSR只是获取证书时用一下
3、常用的证书格式只有PEM和DER两种,区别为是否加密
4、P7B、P12、JKS,只是存放证书的小数据库而已
但有件事情,让这个问题变的复杂了一些,那就是后缀名并不能让你直接区分格式,比如CRT、CER这样的后缀名,只告诉你这是一个证书,但没有告诉你是什么格式。所以要么自己用文本工具及openssl查看一下,判断一下格式咯。
二、常用证书格式转换
#PEM to DER openssl x509 -outform der -in certificate.pem -out certificate.der #PEM to P7B openssl crl2pkcs7 -nocrl -certfile certificate.cer -out certificate.p7b -certfile CACert.cer #PEM to PFX/P12 openssl pkcs12 -export -out certificate.p12 -inkey privateKey.key -in certificate.crt -certfile CACert.crt #DER to PEM openssl x509 -inform der -in certificate.cer -out certificate.pem #P7B to PEM openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer #P7B to PFX/P12 openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer openssl pkcs12 -export -in certificate.cer -inkey privateKey.key -out certificate.p12 -certfile CACert.cer #PFX/P12 to PEM openssl pkcs12 -in certificate.p12 -out certificate.cer -nodes #JKS to P12 keytool -importkeystore -srckeystore keystore.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore keystore.p12 #P12 to JKS keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore keystore.jks
C# Https Soap Client
1、Soap Https Soap Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
namespace IISSoapClientTest
{
class Program
{
public static void HelloHttp(string url)
{
Hello h = new Hello(url);
string ans = h.HelloWorld("C# http client");
Console.WriteLine(ans);
Console.WriteLine();
}
//同样的证书,IIS可以过,Tomcat过不去
public static void HelloHttps(string url,String certPath)
{
X509CertificateCollection certs = new X509CertificateCollection();
X509Certificate cert = X509Certificate.CreateFromCertFile(certPath);
Hello h = new Hello(url);
h.ClientCertificates.Add(cert);
string ans = h.HelloWorld("C# https client");
Console.WriteLine(ans);
Console.WriteLine();
}
//绕过证书检查
public static void HelloHttpsWithRemoteCertificateValidationCallback(string url)
{
//ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(RemoteCertificateValidationCallback);
Hello h = new Hello(url);
string ans = h.HelloWorld("C# https client");
Console.WriteLine(ans);
Console.WriteLine();
}
private static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate,
X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
static void Main(string[] args)
{
//HelloHttp("http://127.0.0.1:80/Hello.asmx");
//HelloHttps("https://127.0.0.1:443/Hello.asmx");
//HelloHttpsWithRemoteCertificateValidationCallback("https://127.0.0.1:443/Hello.asmx");
//HelloHttp("http://127.0.0.1:8080/SoapTest/services/HelloService");
HelloHttps("https://127.0.0.1:8443/SoapTest/services/HelloService", @"D:\DiskE\Projects\VS2010\TestProjects\SSLSocket\myKeyStore.cer");
//HelloHttpsWithRemoteCertificateValidationCallback("https://127.0.0.1:8443/SoapTest/services/HelloService");
}
}
}
Java Https Soap Server(Tomcat-Axis2)
1、%Tomcat%/server/server.xml
找到下面一段:
<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->
替换为:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" disableUploadTimeout="true" enableLookups="false" keystoreFile="D:/JavaContainer/apache-tomcat-6.0.35-x86/myKeyStore.jks" keystorePass="sslTestPwd" />
这样,就可以用https://127.0.0.1:8443访问Tomcat了。
2、在需要使用https项目的axis2.xml文件中,增加下面内容
<!--修改-->
<transportReceiver name="http"
class="org.apache.axis2.transport.http.AxisServletListener">
<parameter name="port">8080</parameter>
</transportReceiver>
<!--新增-->
<transportReceiver name="https"
class="org.apache.axis2.transport.http.AxisServletListener">
<parameter name="port">8443</parameter>
</transportReceiver>
这样,该WebService就可以使用https进行访问了:)
C# Https Soap Server(IIS7)
1、首先准备一个p12格式的服务端证书
无论是购买,还是用openssl或java keytool生成自签名证书都可以
2、在IIS7的根目录,选中“安全性->根目录证书”,选择“导入”即可
3、如果显示证书链有问题,则在IE中导入CA证书就好了
4、在需要HTTPS的网站上,选择“绑定”,绑定类型为https,选择需要的证书
5、在客户端的IE中,导入CA证书就好了
Java Https Soap Client(Axis2)
1、SoapClient
package com.neohope;
import java.net.URL;
import java.rmi.RemoteException;
public class SoapClientTest {
public static void HelloHttp(String url) throws RemoteException
{
HelloStub h = new HelloStub(url);
com.neohope.HelloStub.HelloWorld hello = new com.neohope.HelloStub.HelloWorld();
hello.setName("Java http client");
com.neohope.HelloStub.HelloWorldResponse rsp = h.helloWorld(hello);
System.out.println(rsp.getHelloWorldResult());
}
public static void HelloHttps(String url,String trustStorePath,String trustStorePwd) throws RemoteException
{
URL jksurl = SoapClientTest.class.getClassLoader().getResource(
"myTrustStore.jks");
String jks = jksurl.getFile();
System.setProperty("javax.net.ssl.trustStore", jks);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePwd);
HelloStub h = new HelloStub(url);
com.neohope.HelloStub.HelloWorld hello = new com.neohope.HelloStub.HelloWorld();
hello.setName("Java https client");
com.neohope.HelloStub.HelloWorldResponse rsp = h.helloWorld(hello);
System.out.println(rsp.getHelloWorldResult());
}
public static void main(String[] args) throws RemoteException
{
//HelloHttp("http://localhost:80/Hello.asmx");
HelloHttps("https://localhost:443/Hello.asmx","myTrustStore.jks","sslTestPwd");
}
}
2、SoapClientWithContextTest
package com.neohope;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.rmi.RemoteException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
public class SoapClientWithContextTest {
public static void HelloHttp(String url) throws RemoteException
{
HelloStub h = new HelloStub(url);
com.neohope.HelloStub.HelloWorld hello = new com.neohope.HelloStub.HelloWorld();
hello.setName("Java http client");
com.neohope.HelloStub.HelloWorldResponse rsp = h.helloWorld(hello);
System.out.println(rsp.getHelloWorldResult());
}
public static void HelloHttps(String url,String trustStorePath,String trustStorePwd) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException, FileNotFoundException, IOException
{
URL jksurl = SoapClientTest.class.getClassLoader().getResource(
"myTrustStore.jks");
String jks = jksurl.getFile();
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream(jks), trustStorePwd.toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1");
//SSLContext sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(new KeyManager[0], trustManagerFactory.getTrustManagers(), null);
SSLContext.setDefault(sslContext);
HelloStub h = new HelloStub(url);
com.neohope.HelloStub.HelloWorld hello = new com.neohope.HelloStub.HelloWorld();
hello.setName("Java https client");
com.neohope.HelloStub.HelloWorldResponse rsp = h.helloWorld(hello);
System.out.println(rsp.getHelloWorldResult());
}
public static void main(String[] args) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException
{
//HelloHttp("http://localhost:80/Hello.asmx");
HelloHttps("https://localhost:443/Hello.asmx","myTrustStore.jks","sslTestPwd");
}
}
3、SoapClientWithTrustManagerTest
可以绕过证书检查
package com.neohope;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.RemoteException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class SoapClientWithTrustManagerTest {
public static void HelloHttp(String url) throws RemoteException
{
HelloStub h = new HelloStub(url);
com.neohope.HelloStub.HelloWorld hello = new com.neohope.HelloStub.HelloWorld();
hello.setName("Java http client");
com.neohope.HelloStub.HelloWorldResponse rsp = h.helloWorld(hello);
System.out.println(rsp.getHelloWorldResult());
}
public static void HelloHttps(String url,String trustStorePath,String trustStorePwd) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException, FileNotFoundException, IOException
{
SSLContext sslContext = SSLContext.getInstance("TLSv1");
//SSLContext sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() }, new SecureRandom());
SSLContext.setDefault(sslContext);
HelloStub h = new HelloStub(url);
com.neohope.HelloStub.HelloWorld hello = new com.neohope.HelloStub.HelloWorld();
hello.setName("Java https client");
com.neohope.HelloStub.HelloWorldResponse rsp = h.helloWorld(hello);
System.out.println(rsp.getHelloWorldResult());
}
private static class DefaultTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
public static void main(String[] args) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException
{
//HelloHttp("http://localhost:80/Hello.asmx");
HelloHttps("https://localhost:443/Hello.asmx","myTrustStore.jks","sslTestPwd");
}
}
SSLSocket Java Part4
1、证书生成
generateKey.bat
Set Path=%JAVA_HOME%\bin;%PATH% #生成私钥 keytool -validity 10000 -genkey -alias sslTestKey -keystore myKeyStore.jks -keypass sslTestPwd -storepass sslTestPwd -dname "CN=AtlasTiger, OU=AtlasTiger, O=AtlasTiger, L=ShangHai, ST=ShangHai, C=CN" pause
2、导出公钥证书Cert
exportCert.bat
Set Path=%JAVA_HOME%\bin;%PATH% #导出证书 keytool -export -keystore myKeyStore.jks -storepass sslTestPwd -keypass sslTestPwd -alias sslTestKey -file myKeyStore.crt pause
3、导出TurstStore
exportTrustSotre.bat
Set Path=%JAVA_HOME%\bin;%PATH% #导入证书生成TurstStore keytool -import -file myKeyStore.crt -alias sslTestKey -keystore myTrustStore.jks -keypass sslTestPwd -storepass sslTestPwd pause
4、导出私钥P12格式
exportP12.bat
Set Path=%JAVA_HOME%\bin;%PATH% keytool -importkeystore -srckeystore myKeyStore.jks -destkeystore myKeyStore.p12 -deststoretype PKCS12 -srcstorepass password -deststorepass password pause
SSLSocket C# Part1
1、SSLSocket Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
namespace SSLSocket
{
class SSLSocketServer
{
static X509Certificate serverCertificate = null;
static String delimiter = "=========================================================";
public static void RunServer(String ip,int port,String p12Path)
{
serverCertificate = new X509Certificate2(p12Path, "sslTestPwd");
TcpListener listener = new TcpListener(IPAddress.Parse(ip), port);
listener.Start();
while (true)
{
try
{
TcpClient client = listener.AcceptTcpClient();
ProcessClient(client);
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
}
}
static void ProcessClient(TcpClient client)
{
SslStream sslStream = new SslStream(client.GetStream(), false);
try
{
//sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls | SslProtocols.Ssl2 | SslProtocols.Ssl3 | SslProtocols.None, true);
sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Ssl2 | SslProtocols.Ssl3, true);
DisplaySecurityLevel(sslStream);
DisplayCertificateInformation(sslStream);
sslStream.ReadTimeout = 5000;
sslStream.WriteTimeout = 5000;
string messageData = ReadMessage(sslStream);
Console.WriteLine(delimiter);
Console.WriteLine("收到信息: {0}", messageData);
Console.WriteLine(delimiter);
//byte[] message = Encoding.UTF8.GetBytes("Hello from the server.");
//Console.WriteLine("Sending hello message.");
//sslStream.Write(message);
}
catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
sslStream.Close();
client.Close();
return;
}
finally
{
sslStream.Close();
client.Close();
}
}
static string ReadMessage(SslStream sslStream)
{
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
bytes = sslStream.Read(buffer, 0, buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
if (messageData.ToString().IndexOf("") != -1)
{
break;
}
}
while (bytes != 0);
return messageData.ToString();
}
static void DisplaySecurityLevel(SslStream stream)
{
Console.WriteLine(delimiter);
Console.WriteLine("通讯协议: {0}", stream.SslProtocol);
Console.WriteLine("加密算法: {0} strength {1}", stream.CipherAlgorithm, stream.CipherStrength);
Console.WriteLine("哈希算法: {0} strength {1}", stream.HashAlgorithm, stream.HashStrength);
Console.WriteLine("密钥交换算法: {0} strength {1}", stream.KeyExchangeAlgorithm, stream.KeyExchangeStrength);
Console.WriteLine(delimiter);
}
static void DisplayCertificateInformation(SslStream stream)
{
Console.WriteLine(delimiter);
Console.WriteLine("证书吊销列表检查: {0}", stream.CheckCertRevocationStatus);
X509Certificate localCertificate = stream.LocalCertificate;
if (stream.LocalCertificate != null)
{
Console.WriteLine("本地证书签发者: {0}", localCertificate.Subject);
Console.WriteLine("本地证书有效期: {0}~{1}", localCertificate.GetEffectiveDateString(),
localCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("本地证书为空");
}
X509Certificate remoteCertificate = stream.RemoteCertificate;
if (stream.RemoteCertificate != null)
{
Console.WriteLine("远程证书签发者: {0}", remoteCertificate.Subject);
Console.WriteLine("远程证书有效期: {0}至{1}", remoteCertificate.GetEffectiveDateString(),
remoteCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("远程证书为空");
}
Console.WriteLine(delimiter);
}
}
}
2、SSLSocket Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
namespace SSLSocketClient
{
class SSLSocketClient
{
//回调函数验证证书
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch || sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
{
return true;
}
return false;
}
public static void SendMessage(string ip, int port,String certPath, String msg)
{
TcpClient client = new TcpClient(ip, port);
SslStream sslStream = new SslStream(client.GetStream(),
false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
X509CertificateCollection certs = new X509CertificateCollection();
X509Certificate cert = X509Certificate.CreateFromCertFile(certPath);
certs.Add(cert);
try
{
sslStream.AuthenticateAsClient("AtlasTiger", certs, SslProtocols.Tls, false);
//sslStream.AuthenticateAsClient("AtlasTiger", certs, SslProtocols.Ssl3, false);
//sslStream.AuthenticateAsClient("AtlasTiger", certs, SslProtocols.Ssl2, false);
//sslStream.AuthenticateAsClient("AtlasTiger", certs, SslProtocols.None, false);
}
catch (AuthenticationException e)
{
Console.WriteLine("Authentication failed : " + e);
client.Close();
return;
}
byte[] messsage = Encoding.UTF8.GetBytes(msg);
sslStream.Write(messsage);
sslStream.Flush();
client.Close();
}
}
}
SSLSocket Java Part3
1、SSLSocket Client绕过证书检查
package com.ats.ssl.socket;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class ClientWithTrustManager {
public static void connectAndSend(String trustStorePath,
String trustStorePwd, String ip, int port, String msg) throws IOException, NoSuchAlgorithmException, KeyManagementException{
SSLContext sslContext = SSLContext.getInstance("TLS");
//SSLContext sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() }, new SecureRandom());
SSLContext.setDefault(sslContext);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
SSLSocket sslsocket = (SSLSocket) sslSocketFactory.createSocket(
"localhost", 9999);
try {
OutputStream outputstream = sslsocket.getOutputStream();
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(
outputstreamwriter);
bufferedwriter.write(msg);
bufferedwriter.flush();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
sslsocket.close();
}
}
private static class DefaultTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
public static void main(String[] args) throws Exception {
try {
URL url = Server.class.getClassLoader().getResource(
"myTrustStore.jks");
String jks = url.getFile();
connectAndSend(jks, "sslTestPwd", "127.0.0.1", 9999,
"This msg is from Java SSL Client :)");
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
SSLSocket Java Part2
1、SSLSocket Java Server使用SSLContext
package com.ats.ssl.socket;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class ServerWithContext {
static String delimiter = "=========================================================";
public static void startListen(String keyStorePath, String keyStorePwd, int port) throws IOException, KeyStoreException, NoSuchAlgorithmException,
CertificateException, UnrecoverableKeyException, KeyManagementException {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(keyStorePath), keyStorePwd.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, keyStorePwd.toCharArray());
//SSLContext sslContext = SSLContext.getInstance("TLSv1");
SSLContext sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[0], null);
SSLServerSocketFactory sslserversocketfactory = sslContext.getServerSocketFactory();
SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(port);
while (true) {
SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
DisplaySecurityLevel(sslsocket);
DisplayCertificateInformation(sslsocket);
try {
InputStream inputstream = sslsocket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
System.out.println(delimiter);
String string = null;
while ((string = bufferedreader.readLine()) != null) {
System.out.println(string);
System.out.flush();
}
System.out.println(delimiter);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
sslsocket.close();
}
}
}
static void DisplaySecurityLevel(SSLSocket sslsocket) {
System.out.println(delimiter);
SSLSession session = sslsocket.getSession();
System.out.println("通讯协议: " + session.getProtocol());
System.out.println("加密方式: " + session.getCipherSuite());
System.out.println(delimiter);
}
static void DisplayCertificateInformation(SSLSocket sslsocket) {
System.out.println(delimiter);
Certificate[] localCertificates = sslsocket.getSession().getLocalCertificates();
if (localCertificates == null || localCertificates.length == 0) {
System.out.println("本地证书为空");
} else {
Certificate cert = localCertificates[0];
System.out.println("本地证书类型: " + cert.getType());
if (cert.getType().equals("X.509")) {
X509Certificate x509 = (X509Certificate) cert;
System.out.println("本地证书签发者: " + x509.getIssuerDN());
System.out.println("本地证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
}
}
try {
Certificate[] peerCertificates = sslsocket.getSession().getPeerCertificates();
if (peerCertificates == null || peerCertificates.length == 0) {
System.out.println("远程证书为空");
} else {
Certificate cert = peerCertificates[0];
System.out.println("远程证书类型: " + cert.getType());
if (cert.getType().equals("X.509")) {
X509Certificate x509 = (X509Certificate) cert;
System.out.println("远程证书签发者: " + x509.getIssuerDN());
System.out.println("远程证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
}
}
} catch (SSLPeerUnverifiedException e) {
// e.printStackTrace();
System.out.println("远程证书为空");
}
System.out.println(delimiter);
}
public static void main(String[] arstring) {
try {
URL url = ServerWithContext.class.getClassLoader().getResource("myKeyStore.jks");
String jks = url.getFile();
startListen(jks, "sslTestPwd", 9999);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
2、SSLSocket Java Client使用SSLContext
package com.ats.ssl.socket;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
public class ClientWithContext {
public static void connectAndSend(String trustStorePath,
String trustStorePwd, String ip, int port, String msg) throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException, UnrecoverableKeyException{
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream(trustStorePath), trustStorePwd.toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1");
//SSLContext sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(new KeyManager[0], trustManagerFactory.getTrustManagers(), null);
SSLContext.setDefault(sslContext);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
SSLSocket sslsocket = (SSLSocket) sslSocketFactory.createSocket(
"localhost", 9999);
try {
OutputStream outputstream = sslsocket.getOutputStream();
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(
outputstreamwriter);
bufferedwriter.write(msg);
bufferedwriter.flush();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
sslsocket.close();
}
}
public static void main(String[] args) throws Exception {
try {
URL url = Server.class.getClassLoader().getResource(
"myTrustStore.jks");
String jks = url.getFile();
connectAndSend(jks, "sslTestPwd", "127.0.0.1", 9999,
"This msg is from Java SSL Client :)");
} catch (Exception exception) {
exception.printStackTrace();
}
}
}