1.HTTPS握手过程模拟

以下文章来自:http://kingj.iteye.com/blog/2103662

1.1准备工作

1、创建java证书:

C:\> keytool -genkey -alias wangyi -keypass wangyi -keyalg RSA -keysize 1024 -keystore https.keystore -storepass wangyi

2、将创建的证书保存到C盘(为了方便演示)

C:\>keytool -export -keystore https.keystore -alias wangyi -file https.crt -storepass wangyi

1.2类的说明

代码包含6个类,分别为:

名称 说明
CertifcateUtils 证书操作类
DesCoder Des对称加密和解密工具类
HttpsMockBase https父类
HttpsMockClient client类
HttpsMockServer 服务器类
SocketUtils socket工具类

CertifacateUtils.java

package httpsmock;import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
/*** Created by kingj on 2014/8/13.*/
public class CertifcateUtils {public static byte[] readCertifacates() throws Exception{CertificateFactory factory=CertificateFactory.getInstance("X.509");InputStream in=new FileInputStream("c:/https.crt");java.security.cert.Certificate cate=factory.generateCertificate(in);return cate.getEncoded();}public static byte[] readPrivateKey() throws  Exception{KeyStore store=KeyStore.getInstance("JKS");InputStream in=new FileInputStream("c:/https.keystore");store.load(in,"wangyi".toCharArray());PrivateKey pk=(PrivateKey)store.getKey("wangyi","wangyi".toCharArray());return pk.getEncoded();}public static PrivateKey readPrivateKeys() throws  Exception{KeyStore store=KeyStore.getInstance("JKS");InputStream in=new FileInputStream("c:/https.keystore");store.load(in,"wangyi".toCharArray());PrivateKey pk=(PrivateKey)store.getKey("wangyi","wangyi".toCharArray());return pk;}public static PublicKey readPublicKeys() throws  Exception{CertificateFactory factory=CertificateFactory.getInstance("X.509");InputStream in=new FileInputStream("c:/https.crt");java.security.cert.Certificate cate=factory.generateCertificate(in);return cate.getPublicKey();}public static  java.security.cert.Certificate createCertiface(byte b[]) throws Exception{CertificateFactory factory=CertificateFactory.getInstance("X.509");InputStream in=new ByteArrayInputStream(b);java.security.cert.Certificate cate=factory.generateCertificate(in);return cate;}public static String byte2hex(byte[] b) {String hs = "";String stmp = "";for (int n = 0; n < b.length; n++) {stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));if (stmp.length() == 1) {hs = hs + "0" + stmp;} else {hs = hs + stmp;}}return hs.toUpperCase();}
}


DesCoder.java

package httpsmock;/*** Created by kingj on 2014/8/13.*/
import org.apache.commons.codec.binary.Hex;import java.security.Key;
import java.security.SecureRandom;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;/*** DES Coder<br/>* secret key length:   56 bit, default:    56 bit<br/>* mode:    ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128<br/>* padding: Nopadding/PKCS5Padding/ISO10126Padding/* @author Aub**/
public class DesCoder {/*** 密钥算法*/private static final String KEY_ALGORITHM = "DES";private static final String DEFAULT_CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";
//  private static final String DEFAULT_CIPHER_ALGORITHM = "DES/ECB/ISO10126Padding";/*** 初始化密钥** @return byte[] 密钥* @throws Exception*/public static byte[] initSecretKey(SecureRandom random) throws Exception{//返回生成指定算法的秘密密钥的 KeyGenerator 对象KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);//初始化此密钥生成器,使其具有确定的密钥大小kg.init(random);//生成一个密钥SecretKey  secretKey = kg.generateKey();return secretKey.getEncoded();}/*** 转换密钥** @param key  二进制密钥* @return Key 密钥* @throws Exception*/public static Key toKey(byte[] key) throws Exception{//实例化DES密钥规则DESKeySpec dks = new DESKeySpec(key);//实例化密钥工厂SecretKeyFactory skf = SecretKeyFactory.getInstance(KEY_ALGORITHM);//生成密钥SecretKey  secretKey = skf.generateSecret(dks);return secretKey;}/*** 加密** @param data  待加密数据* @param key  密钥* @return byte[] 加密数据* @throws Exception*/public static byte[] encrypt(byte[] data,Key key) throws Exception{return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);}/*** 加密** @param data 待加密数据* @param key  二进制密钥* @return byte[]  加密数据* @throws Exception*/public static byte[] encrypt(byte[] data,byte[] key) throws Exception{return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM);}/*** 加密** @param data  待加密数据* @param key  二进制密钥* @param cipherAlgorithm  加密算法/工作模式/填充方式* @return byte[] 加密数据* @throws Exception*/public static byte[] encrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{//还原密钥Key k = toKey(key);return encrypt(data, k, cipherAlgorithm);}/*** 加密** @param data   待加密数据* @param key  密钥* @param cipherAlgorithm 加密算法/工作模式/填充方式* @return byte[] 加密数据* @throws Exception*/public static byte[] encrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{//实例化Cipher cipher = Cipher.getInstance(cipherAlgorithm);//使用密钥初始化,设置为加密模式cipher.init(Cipher.ENCRYPT_MODE, key);//执行操作return cipher.doFinal(data);}/*** 解密** @param data   待解密数据* @param key  二进制密钥* @return byte[]  解密数据* @throws Exception*/public static byte[] decrypt(byte[] data,byte[] key) throws Exception{return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);}/*** 解密** @param data  待解密数据* @param key  密钥* @return byte[] 解密数据* @throws Exception*/public static byte[] decrypt(byte[] data,Key key) throws Exception{return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);}/*** 解密** @param data 待解密数据* @param key  二进制密钥* @param cipherAlgorithm  加密算法/工作模式/填充方式* @return byte[] 解密数据* @throws Exception*/public static byte[] decrypt(byte[] data,byte[] key,String cipherAlgorithm) throws Exception{//还原密钥Key k = toKey(key);return decrypt(data, k, cipherAlgorithm);}/*** 解密** @param data   待解密数据* @param key  密钥* @param cipherAlgorithm 加密算法/工作模式/填充方式* @return byte[] 解密数据* @throws Exception*/public static byte[] decrypt(byte[] data,Key key,String cipherAlgorithm) throws Exception{//实例化Cipher cipher = Cipher.getInstance(cipherAlgorithm);//使用密钥初始化,设置为解密模式cipher.init(Cipher.DECRYPT_MODE, key);//执行操作return cipher.doFinal(data);}private static String  showByteArray(byte[] data){if(null == data){return null;}StringBuilder sb = new StringBuilder("{");for(byte b:data){sb.append(b).append(",");}sb.deleteCharAt(sb.length()-1);sb.append("}");return sb.toString();}}

HttpsMockBase.java

package httpsmock;import com.sun.org.apache.bcel.internal.generic.NEW;import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.Random;/*** Created by kingj on 2014/8/13.*/
public class HttpsMockBase {static PrivateKey privateKey;static PublicKey publicKey;public static boolean byteEquals(byte a[],byte[] b){boolean equals=true;if(a==null || b==null){equals=false;}if(a!=null && b!=null){if(a.length!=b.length){equals=false;}else{for(int i=0;i<a.length;i++){if(a[i]!=b[i]){equals=false;break;}}}}return equals;}public static byte[] decrypt(byte data[]) throws Exception{// 对数据解密Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}public static byte[] decrypt(byte data[],SecureRandom seed) throws Exception{// 对数据解密Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey,seed);return cipher.doFinal(data);}public static byte[] decryptByPublicKey(byte data[],SecureRandom seed) throws Exception{if(publicKey==null){publicKey=CertifcateUtils.readPublicKeys();}// 对数据解密Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());if(seed==null){cipher.init(Cipher.DECRYPT_MODE, publicKey);}else{cipher.init(Cipher.DECRYPT_MODE, publicKey,seed);}return cipher.doFinal(data);}public static byte[] decryptByDes(byte data[],SecureRandom seed) throws Exception{if(publicKey==null){publicKey=CertifcateUtils.readPublicKeys();}// 对数据解密Cipher cipher = Cipher.getInstance("DES");if(seed==null){cipher.init(Cipher.DECRYPT_MODE, publicKey);}else{cipher.init(Cipher.DECRYPT_MODE, publicKey,seed);}return cipher.doFinal(data);}public static byte[] encryptByPublicKey(byte[] data, SecureRandom seed)throws Exception {if(publicKey==null){publicKey=CertifcateUtils.readPublicKeys();}// 对数据加密Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());if(seed==null){cipher.init(Cipher.ENCRYPT_MODE, publicKey);}else{cipher.init(Cipher.ENCRYPT_MODE, publicKey,seed);}return cipher.doFinal(data);}public static String byte2hex(byte[] b) {String hs = "";String stmp = "";for (int n = 0; n < b.length; n++) {stmp = (Integer.toHexString(b[n] & 0XFF));if (stmp.length() == 1) {hs = hs + "0" + stmp;} else {hs = hs +"  " + stmp;}}return hs.toUpperCase();}public static byte[] cactHash(byte[] bytes) {byte[] _bytes = null;try {MessageDigest md = MessageDigest.getInstance("SHA1");md.update(bytes);_bytes = md.digest();} catch (NoSuchAlgorithmException ex) {ex.printStackTrace();}return _bytes;}static String random(){StringBuilder builder=new StringBuilder();Random random=new Random();int seedLength=10;for(int i=0;i<seedLength;i++){builder.append(digits[random.nextInt(seedLength)]);}return builder.toString();}static char[] digits={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j'};}

HttpsMockClient.java

package httpsmock;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.security.Key;
import java.security.SecureRandom;/*** Created by kingj on 2014/8/13.*/
public class HttpsMockClient extends  HttpsMockBase {static DataInputStream in;static DataOutputStream out;static Key key;public static void main(String args[]) throws  Exception{int port=80;Socket s=new Socket("localhost",port);s.setReceiveBufferSize(102400);s.setKeepAlive(true);in=new DataInputStream(s.getInputStream());out=new DataOutputStream(s.getOutputStream());shakeHands();System.out.println("------------------------------------------------------------------");String name="duck";writeBytes(name.getBytes());int len=in.readInt();byte[] msg=readBytes(len);System.out.println("服务器反馈消息:"+byte2hex(msg));Thread.sleep(1000*100);}private static void shakeHands() throws Exception {//第一步 客户端发送自己支持的hash算法String supportHash="SHA1";int length=supportHash.getBytes().length;out.writeInt(length);SocketUtils.writeBytes(out, supportHash.getBytes(), length);//第二步 客户端验证服务器端证书是否合法int skip=in.readInt();byte[] certificate=SocketUtils.readBytes(in,skip);java.security.cert.Certificate cc= CertifcateUtils.createCertiface(certificate);publicKey=cc.getPublicKey();cc.verify(publicKey);System.out.println("客户端校验服务器端证书是否合法:" +true);//第三步  客户端校验服务器端发送过来的证书成功,生成随机数并用公钥加密System.out.println("客户端校验服务器端发送过来的证书成功,生成随机数并用公钥加密");SecureRandom seed=new SecureRandom();int seedLength=2;byte seedBytes[]=seed.generateSeed(seedLength);System.out.println("生成的随机数为 : " + byte2hex(seedBytes));System.out.println("将随机数用公钥加密后发送到服务器");byte[] encrptedSeed=encryptByPublicKey(seedBytes, null);SocketUtils.writeBytes(out,encrptedSeed,encrptedSeed.length);System.out.println("加密后的seed值为 :" + byte2hex(encrptedSeed));String message=random();System.out.println("客户端生成消息为:"+message);System.out.println("使用随机数并用公钥对消息加密");byte[] encrpt=encryptByPublicKey(message.getBytes(),seed);System.out.println("加密后消息位数为 : " +encrpt.length);SocketUtils.writeBytes(out,encrpt,encrpt.length);System.out.println("客户端使用SHA1计算消息摘要");byte hash[]=cactHash(message.getBytes());System.out.println("摘要信息为:"+byte2hex(hash));System.out.println("消息加密完成,摘要计算完成,发送服务器");SocketUtils.writeBytes(out,hash,hash.length);System.out.println("客户端向服务器发送消息完成,开始接受服务器端发送回来的消息和摘要");System.out.println("接受服务器端发送的消息");int serverMessageLength=in.readInt();byte[] serverMessage=SocketUtils.readBytes(in,serverMessageLength);System.out.println("服务器端的消息内容为 :" + byte2hex(serverMessage));System.out.println("开始用之前生成的随机密码和DES算法解密消息,密码为:"+byte2hex(seedBytes));byte[] desKey= DesCoder.initSecretKey(new SecureRandom(seedBytes));key=DesCoder.toKey(desKey);byte[] decrpytedServerMsg=DesCoder.decrypt(serverMessage, key);System.out.println("解密后的消息为:"+byte2hex(decrpytedServerMsg));int serverHashLength=in.readInt();byte[] serverHash=SocketUtils.readBytes(in,serverHashLength);System.out.println("开始接受服务器端的摘要消息:"+byte2hex(serverHash));byte[] serverHashValues=cactHash(decrpytedServerMsg);System.out.println("计算服务器端发送过来的消息的摘要 : " +byte2hex(serverHashValues));System.out.println("判断服务器端发送过来的hash摘要是否和计算出的摘要一致");boolean isHashEquals=byteEquals(serverHashValues,serverHash);if(isHashEquals){System.out.println("验证完成,握手成功");}else{System.out.println("验证失败,握手失败");}}public static byte[] readBytes(int length) throws  Exception{byte[] undecrpty=SocketUtils.readBytes(in,length);System.out.println("读取未解密消息:"+byte2hex(undecrpty));return DesCoder.decrypt(undecrpty,key);}public static void writeBytes(byte[] data) throws  Exception{byte[] encrpted=DesCoder.encrypt(data,key);System.out.println("写入加密后消息:"+byte2hex(encrpted));SocketUtils.writeBytes(out,encrpted,encrpted.length);}
}

HttpsMockServer.java

package httpsmock;import javax.net.ServerSocketFactory;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.Key;
import java.security.SecureRandom;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** Created by kingj on 2014/8/13.*/
public class HttpsMockServer extends HttpsMockBase {static DataInputStream in;static DataOutputStream out;static String hash;static Key key;static ExecutorService executorService= Executors.newFixedThreadPool(20);public static void main(String args[]) throws Exception{int port=80;ServerSocket ss= ServerSocketFactory.getDefault().createServerSocket(port);ss.setReceiveBufferSize(102400);ss.setReuseAddress(false);while(true){try {final Socket s = ss.accept();doHttpsShakeHands(s);executorService.execute(new Runnable() {@Overridepublic void run() {doSocketTransport(s);}});}catch (Exception e){e.printStackTrace();}}}private static void doSocketTransport(Socket s){try{System.out.println("--------------------------------------------------------");int length=in.readInt();byte[] clientMsg=readBytes(length);System.out.println("客户端指令内容为:" + byte2hex(clientMsg));writeBytes("服务器已经接受请求".getBytes());}catch (Exception ex){ex.printStackTrace();}}public static byte[] readBytes(int length) throws  Exception{byte[] undecrpty=SocketUtils.readBytes(in,length);System.out.println("读取未解密消息:"+byte2hex(undecrpty));return DesCoder.decrypt(undecrpty,key);}public static void writeBytes(byte[] data) throws  Exception{byte[] encrpted=DesCoder.encrypt(data,key);System.out.println("写入加密后消息:"+byte2hex(encrpted));SocketUtils.writeBytes(out,encrpted,encrpted.length);}private static void doHttpsShakeHands(Socket s) throws Exception {in=new DataInputStream(s.getInputStream());out=new DataOutputStream(s.getOutputStream());//第一步 获取客户端发送的支持的验证规则,包括hash算法,这里选用SHA1作为hashint length=in.readInt();in.skipBytes(4);byte[] clientSupportHash=SocketUtils.readBytes(in,length);String clientHash=new String(clientSupportHash);hash=clientHash;System.out.println("客户端发送了hash算法为:"+clientHash);//第二步,发送服务器证书到客户端byte[] certificateBytes=CertifcateUtils.readCertifacates();privateKey=CertifcateUtils.readPrivateKeys();System.out.println("发送证书给客户端,字节长度为:"+certificateBytes.length);System.out.println("证书内容为:" + byte2hex(certificateBytes));SocketUtils.writeBytes(out, certificateBytes, certificateBytes.length);System.out.println("获取客户端通过公钥加密后的随机数");int secureByteLength=in.readInt();byte[] secureBytes=SocketUtils.readBytes(in, secureByteLength);System.out.println("读取到的客户端的随机数为:"+byte2hex(secureBytes));byte secureSeed[]=decrypt(secureBytes);System.out.println("解密后的随机数密码为:" +byte2hex(secureSeed));//第三步 获取客户端加密字符串int skip=in.readInt();System.out.println("第三步 获取客户端加密消息,消息长度为 :" +skip);byte[] data=SocketUtils.readBytes(in,skip);System.out.println("客户端发送的加密消息为 : " +byte2hex(data));System.out.println("用私钥对消息解密,并计算SHA1的hash值");byte message[] =decrypt(data,new SecureRandom(secureBytes));byte serverHash[]=cactHash(message);System.out.println("获取客户端计算的SHA1摘要");int hashSkip=in.readInt();byte[] clientHashBytes=SocketUtils.readBytes(in,hashSkip);System.out.println("客户端SHA1摘要为 : " + byte2hex(clientHashBytes));System.out.println("开始比较客户端hash和服务器端从消息中计算的hash值是否一致");boolean isHashEquals=byteEquals(serverHash,clientHashBytes);System.out.println("是否一致结果为 : " + isHashEquals);System.out.println("第一次校验客户端发送过来的消息和摘译一致,服务器开始向客户端发送消息和摘要");System.out.println("生成密码用于加密服务器端消息,secureRandom : "+byte2hex(secureSeed));SecureRandom secureRandom=new SecureRandom(secureSeed);String randomMessage=random();System.out.println("服务器端生成的随机消息为 : "+randomMessage);System.out.println("用DES算法并使用客户端生成的随机密码对消息加密");byte[] desKey=DesCoder.initSecretKey(secureRandom);key=DesCoder.toKey(desKey);byte serverMessage[]=DesCoder.encrypt(randomMessage.getBytes(), key);SocketUtils.writeBytes(out,serverMessage,serverMessage.length);System.out.println("服务器端发送的机密后的消息为:"+byte2hex(serverMessage)+",加密密码为:"+byte2hex(secureSeed));System.out.println("服务器端开始计算hash摘要值");byte serverMessageHash[]=cactHash(randomMessage.getBytes());System.out.println("服务器端计算的hash摘要值为 :" +byte2hex(serverMessageHash));SocketUtils.writeBytes(out,serverMessageHash,serverMessageHash.length);System.out.println("握手成功,之后所有通信都将使用DES加密算法进行加密");}}

SocketUtils.java

package httpsmock;import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Arrays;/*** Created by kingj on 2014/8/13.*/
public class SocketUtils {public static void close(Socket s){try {s.shutdownInput();s.shutdownOutput();} catch (IOException e) {e.printStackTrace();}}public static byte[] readBytes(DataInputStream in,int length) throws IOException {int r=0;byte[] data=new byte[length];while(r<length){r+=in.read(data,r,length-r);}return data;}public static void writeBytes(DataOutputStream out,byte[] bytes,int length) throws IOException{out.writeInt(length);out.write(bytes,0,length);out.flush();}
}

测试证书下载地址: https-keys.zip

2.Java加密解密算法工具类实现

以下文章来自:http://snowolf.iteye.com/blog/397693

2.1加密解密基础工具类

Coder.java

import java.security.MessageDigest;import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;/*** 基础加密组件* * @author 梁栋* @version 1.0* @since 1.0*/
public abstract class Coder {public static final String KEY_SHA = "SHA";public static final String KEY_MD5 = "MD5";/*** MAC算法可选以下多种算法* * <pre>* HmacMD5 * HmacSHA1 * HmacSHA256 * HmacSHA384 * HmacSHA512* </pre>*/public static final String KEY_MAC = "HmacMD5";/*** BASE64解密* * @param key* @return* @throws Exception*/public static byte[] decryptBASE64(String key) throws Exception {return (new BASE64Decoder()).decodeBuffer(key);}/*** BASE64加密* * @param key* @return* @throws Exception*/public static String encryptBASE64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}/*** MD5加密* * @param data* @return* @throws Exception*/public static byte[] encryptMD5(byte[] data) throws Exception {MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);md5.update(data);return md5.digest();}/*** SHA加密* * @param data* @return* @throws Exception*/public static byte[] encryptSHA(byte[] data) throws Exception {MessageDigest sha = MessageDigest.getInstance(KEY_SHA);sha.update(data);return sha.digest();}/*** 初始化HMAC密钥* * @return* @throws Exception*/public static String initMacKey() throws Exception {KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);SecretKey secretKey = keyGenerator.generateKey();return encryptBASE64(secretKey.getEncoded());}/*** HMAC加密* * @param data* @param key* @return* @throws Exception*/public static byte[] encryptHMAC(byte[] data, String key) throws Exception {SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);Mac mac = Mac.getInstance(secretKey.getAlgorithm());mac.init(secretKey);return mac.doFinal(data);}
}

CoderTest.java

import static org.junit.Assert.*;import org.junit.Test;/*** * @author 梁栋* @version 1.0* @since 1.0*/
public class CoderTest {@Testpublic void test() throws Exception {String inputStr = "简单加密";System.err.println("原文:\n" + inputStr);byte[] inputData = inputStr.getBytes();String code = Coder.encryptBASE64(inputData);System.err.println("BASE64加密后:\n" + code);byte[] output = Coder.decryptBASE64(code);String outputStr = new String(output);System.err.println("BASE64解密后:\n" + outputStr);// 验证BASE64加密解密一致性assertEquals(inputStr, outputStr);// 验证MD5对于同一内容加密是否一致assertArrayEquals(Coder.encryptMD5(inputData), Coder.encryptMD5(inputData));// 验证SHA对于同一内容加密是否一致assertArrayEquals(Coder.encryptSHA(inputData), Coder.encryptSHA(inputData));String key = Coder.initMacKey();System.err.println("Mac密钥:\n" + key);// 验证HMAC对于同一内容,同一密钥加密是否一致assertArrayEquals(Coder.encryptHMAC(inputData, key), Coder.encryptHMAC(inputData, key));BigInteger md5 = new BigInteger(Coder.encryptMD5(inputData));System.err.println("MD5:\n" + md5.toString(16));BigInteger sha = new BigInteger(Coder.encryptSHA(inputData));System.err.println("SHA:\n" + sha.toString(32));BigInteger mac = new BigInteger(Coder.encryptHMAC(inputData, inputStr));System.err.println("HMAC:\n" + mac.toString(16));}
}

2.2证书组件工具类

CertificateCoder.java

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;import javax.crypto.Cipher;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;/*** 证书组件* * @author 梁栋* @version 1.0* @since 1.0*/
public abstract class CertificateCoder extends Coder {/*** Java密钥库(Java Key Store,JKS)KEY_STORE*/public static final String KEY_STORE = "JKS";public static final String X509 = "X.509";public static final String SunX509 = "SunX509";public static final String SSL = "SSL";/*** 由KeyStore获得私钥* * @param keyStorePath* @param alias* @param password* @return* @throws Exception*/private static PrivateKey getPrivateKey(String keyStorePath, String alias,String password) throws Exception {KeyStore ks = getKeyStore(keyStorePath, password);PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());return key;}/*** 由Certificate获得公钥* * @param certificatePath* @return* @throws Exception*/private static PublicKey getPublicKey(String certificatePath)throws Exception {Certificate certificate = getCertificate(certificatePath);PublicKey key = certificate.getPublicKey();return key;}/*** 获得Certificate* * @param certificatePath* @return* @throws Exception*/private static Certificate getCertificate(String certificatePath)throws Exception {CertificateFactory certificateFactory = CertificateFactory.getInstance(X509);FileInputStream in = new FileInputStream(certificatePath);Certificate certificate = certificateFactory.generateCertificate(in);in.close();return certificate;}/*** 获得Certificate* * @param keyStorePath* @param alias* @param password* @return* @throws Exception*/private static Certificate getCertificate(String keyStorePath,String alias, String password) throws Exception {KeyStore ks = getKeyStore(keyStorePath, password);Certificate certificate = ks.getCertificate(alias);return certificate;}/*** 获得KeyStore* * @param keyStorePath* @param password* @return* @throws Exception*/private static KeyStore getKeyStore(String keyStorePath, String password)throws Exception {FileInputStream is = new FileInputStream(keyStorePath);KeyStore ks = KeyStore.getInstance(KEY_STORE);ks.load(is, password.toCharArray());is.close();return ks;}/*** 私钥加密* * @param data* @param keyStorePath* @param alias* @param password* @return* @throws Exception*/public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath,String alias, String password) throws Exception {// 取得私钥PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);// 对数据加密Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 私钥解密* * @param data* @param keyStorePath* @param alias* @param password* @return* @throws Exception*/public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath,String alias, String password) throws Exception {// 取得私钥PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);// 对数据加密Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 公钥加密* * @param data* @param certificatePath* @return* @throws Exception*/public static byte[] encryptByPublicKey(byte[] data, String certificatePath)throws Exception {// 取得公钥PublicKey publicKey = getPublicKey(certificatePath);// 对数据加密Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 公钥解密* * @param data* @param certificatePath* @return* @throws Exception*/public static byte[] decryptByPublicKey(byte[] data, String certificatePath)throws Exception {// 取得公钥PublicKey publicKey = getPublicKey(certificatePath);// 对数据加密Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 验证Certificate* * @param certificatePath* @return*/public static boolean verifyCertificate(String certificatePath) {return verifyCertificate(new Date(), certificatePath);}/*** 验证Certificate是否过期或无效* * @param date* @param certificatePath* @return*/public static boolean verifyCertificate(Date date, String certificatePath) {boolean status = true;try {// 取得证书Certificate certificate = getCertificate(certificatePath);// 验证证书是否过期或无效status = verifyCertificate(date, certificate);} catch (Exception e) {status = false;}return status;}/*** 验证证书是否过期或无效* * @param date* @param certificate* @return*/private static boolean verifyCertificate(Date date, Certificate certificate) {boolean status = true;try {X509Certificate x509Certificate = (X509Certificate) certificate;x509Certificate.checkValidity(date);} catch (Exception e) {status = false;}return status;}/*** 签名* * @param keyStorePath* @param alias* @param password* * @return* @throws Exception*/public static String sign(byte[] sign, String keyStorePath, String alias,String password) throws Exception {// 获得证书X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath, alias, password);// 获取私钥KeyStore ks = getKeyStore(keyStorePath, password);// 取得私钥PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password.toCharArray());// 构建签名Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());signature.initSign(privateKey);signature.update(sign);return encryptBASE64(signature.sign());}/*** 验证签名* * @param data* @param sign* @param certificatePath* @return* @throws Exception*/public static boolean verify(byte[] data, String sign,String certificatePath) throws Exception {// 获得证书X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);// 获得公钥PublicKey publicKey = x509Certificate.getPublicKey();// 构建签名Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());signature.initVerify(publicKey);signature.update(data);return signature.verify(decryptBASE64(sign));}/*** 验证Certificate* * @param keyStorePath* @param alias* @param password* @return*/public static boolean verifyCertificate(Date date, String keyStorePath,String alias, String password) {boolean status = true;try {Certificate certificate = getCertificate(keyStorePath, alias,password);status = verifyCertificate(date, certificate);} catch (Exception e) {status = false;}return status;}/*** 验证Certificate* * @param keyStorePath* @param alias* @param password* @return*/public static boolean verifyCertificate(String keyStorePath, String alias,String password) {return verifyCertificate(new Date(), keyStorePath, alias, password);}/*** 获得SSLSocektFactory* * @param password*            密码* @param keyStorePath*            密钥库路径* * @param trustKeyStorePath*            信任库路径* @return* @throws Exception*/private static SSLSocketFactory getSSLSocketFactory(String password,String keyStorePath, String trustKeyStorePath) throws Exception {// 初始化密钥库KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(SunX509);KeyStore keyStore = getKeyStore(keyStorePath, password);keyManagerFactory.init(keyStore, password.toCharArray());// 初始化信任库TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(SunX509);KeyStore trustkeyStore = getKeyStore(trustKeyStorePath, password);trustManagerFactory.init(trustkeyStore);// 初始化SSL上下文SSLContext ctx = SSLContext.getInstance(SSL);ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);SSLSocketFactory sf = ctx.getSocketFactory();return sf;}/*** 为HttpsURLConnection配置SSLSocketFactory* * @param conn*            HttpsURLConnection* @param password*            密码* @param keyStorePath*            密钥库路径* * @param trustKeyStorePath*            信任库路径* @throws Exception*/public static void configSSLSocketFactory(HttpsURLConnection conn,String password, String keyStorePath, String trustKeyStorePath)throws Exception {conn.setSSLSocketFactory(getSSLSocketFactory(password, keyStorePath,trustKeyStorePath));}
}

CertificateCoderTest.java

import static org.junit.Assert.*;import java.io.DataInputStream;
import java.io.InputStream;
import java.net.URL;import javax.net.ssl.HttpsURLConnection;import org.junit.Test;/*** * @author 梁栋* @version 1.0* @since 1.0*/
public class CertificateCoderTest {private String password = "123456";private String alias = "www.zlex.org";private String certificatePath = "d:/zlex.cer";private String keyStorePath = "d:/zlex.keystore";private String clientKeyStorePath = "d:/zlex-client.keystore";private String clientPassword = "654321";@Testpublic void test() throws Exception {System.err.println("公钥加密——私钥解密");String inputStr = "Ceritifcate";byte[] data = inputStr.getBytes();byte[] encrypt = CertificateCoder.encryptByPublicKey(data,certificatePath);byte[] decrypt = CertificateCoder.decryptByPrivateKey(encrypt,keyStorePath, alias, password);String outputStr = new String(decrypt);System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);// 验证数据一致assertArrayEquals(data, decrypt);// 验证证书有效assertTrue(CertificateCoder.verifyCertificate(certificatePath));}@Testpublic void testSign() throws Exception {System.err.println("私钥加密——公钥解密");String inputStr = "sign";byte[] data = inputStr.getBytes();byte[] encodedData = CertificateCoder.encryptByPrivateKey(data,keyStorePath, alias, password);byte[] decodedData = CertificateCoder.decryptByPublicKey(encodedData,certificatePath);String outputStr = new String(decodedData);System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);assertEquals(inputStr, outputStr);System.err.println("私钥签名——公钥验证签名");// 产生签名String sign = CertificateCoder.sign(encodedData, keyStorePath, alias,password);System.err.println("签名:\r" + sign);// 验证签名boolean status = CertificateCoder.verify(encodedData, sign,certificatePath);System.err.println("状态:\r" + status);assertTrue(status);}@Testpublic void testHttps() throws Exception {URL url = new URL("https://www.zlex.org/examples/");HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();conn.setDoInput(true);conn.setDoOutput(true);CertificateCoder.configSSLSocketFactory(conn, clientPassword,clientKeyStorePath, clientKeyStorePath);InputStream is = conn.getInputStream();int length = conn.getContentLength();DataInputStream dis = new DataInputStream(is);byte[] data = new byte[length];dis.readFully(data);dis.close();System.err.println(new String(data));conn.disconnect();}
}

2.3Java相关加密解密学习

Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC
Java加密技术(二)——对称加密DES&AES
Java加密技术(三)——PBE算法
Java加密技术(四)——非对称加密算法RSA
Java加密技术(五)——非对称加密算法的由来
Java加密技术(六)——数字签名算法DSA
Java加密技术(七)——非对称加密算法最高ECC
Java加密技术(八)——数字证书
Java加密技术(九)——初探SSL
Java加密技术(十)——单向认证
Java加密技术(十一)——双向认证
Java加密技术(十二)——*.PFX(*.p12)&个人信息交换文件

Java实现HTTPS加密、解密过程相关推荐

  1. HTTPS加密解密过程

    https:在http(超文本传输协议)基础上提出的一种安全的http协议,因此可以称为安全的超文本传输协议.http协议直接放置在TCP协议之上,而https提出在http和TCP中间加上一层加密层 ...

  2. https加密解密过程详解

    要点: https协议对传输内容进行加密,具有更强的安全性,防止被抓包后解析出请求内容. https是建立在ssl之上的http协议. 服务器支持https协议必须安装一套数字证书,所谓数字证书就是一 ...

  3. java公钥加密私钥解密过程_GPG加密解密过程

    GPG加密解密过程 一.Linux系统下 1.安装 yum安装 [root@POC-ORACLE ~]# yum install gnupg 下载安装包安装 https://www.gnupg.org ...

  4. Java常见的加密解密

    Java常见的加密解密 不可逆加密 介绍 应用场景 一致性验证 MD5 可以为文件传输场景中,提供文件的一致性验证. 例如,文件服务器预先提供一个 MD5 校验值,用户下载完文件以后,用 MD5 算法 ...

  5. Web登录使用RSA对密码进行加密解密过程

    RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥.首先简单说一下RSA加密方式(借用知乎上面的理解,通俗易懂): ...

  6. HTTPS加密传输过程

    HTTPS加密传输过程 HTTPS全称Hyper Text Transfer Protocol over SecureSocket Layer,是以安全为目标的HTTP通道,在HTTP的基础上通过传输 ...

  7. asp.net中URL参数加密解密过程

    asp.net中URL参数加密解密过程 加密代码 public static string Encode(string str, string key){DESCryptoServiceProvide ...

  8. 条理清晰的入门:使用Java实现RSA加密解密

    条理清晰的入门:使用Java实现RSA加密解密 什么是RSA 使用Java 需要导入的头文件 生成公钥.私钥 进行加密解密 密钥的存储 密文的存储.读取 什么是RSA 翻一下以前的密码学笔记,找到了! ...

  9. HTTPS加密的过程你了解吗?

    1.HTTPS加密的过程 HTTPS是在HTTP的基础上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版.主要作用是: (1)对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数 ...

  10. php与java的des加密解密

    与第三方接口对接des加密.解密,第三方提供java的des加密解密demo,特记录PHP与java加密解密. import javax.crypto.*; import javax.crypto.s ...

最新文章

  1. 电子邮件成企业主动营销的首选工具
  2. JSP2.0语法初步掌握(学习笔记)
  3. DialogFragment源码分析
  4. The return types for the following stored procedures could not be detected
  5. 3 Python os 文件和目录
  6. struts+hibernate+oracle+easyui实现lazyout组件的简单案例——OpSessionview实现
  7. UVALive 4764 dp
  8. 谷歌宕机,只有运维背锅吗?
  9. 关于zlog库的快速使用教程
  10. java名片生成_HTML5 canvas绘图基础(电子名片生成器源码)
  11. linux下如何实现pgadmin备份,linux下pgAdmin4安装
  12. web 前端面试题50道
  13. 用强化学习制作游戏AI
  14. 工业相机与工业镜头相关参数详解
  15. 邮件中的 请看附件 请知悉,英语怎么说 要比较正式的用语
  16. Matlab表格和时间表中的分组计算
  17. 旋转方阵So easy
  18. Java中四舍五入和四舍六入五成双
  19. 软件测试周刊(第23期):你理想中的工作是什么?
  20. 手把手教你做一个电子胸牌

热门文章

  1. fft变换之后的实际意义
  2. docker-compose up start restart区别
  3. 【商务英语】邮件中的感谢
  4. 怎样禁止系统的信使服务(转)
  5. 介绍一个视频互动直播后台的开源项目
  6. ZYNQ的PL控制PS的DDR
  7. 魔方cfop公式软件_【番外篇】CFOP玩法进阶技巧与衍生解法介绍大全!
  8. Hbase Sql 层 Phoenix 的三个特性Row timestamp, Sequences 和 Salted Tables
  9. Qt文本编辑器开发------纯代码实现
  10. 微机原理-I/O并行接口和并行接口芯片8255A