目录
HTTPS协议的工作流程
- 用户通过浏览器访问HTTPS网站,服务器收到来自用户的请求,会根据用户的浏览器选择所支持的加密和Hash算法,同时返回数字证书给浏览器。包含颁发机构、网址、公钥、证书有效期等信息。
- 浏览器接收到服务器端返回的证书,会对证书内容进行校验,若存在问题就会有一个提示警告;否则就生成随机密钥X,并将随机密钥X使用证书包含的公钥进行加密处理,再将其发送给服务器端。
- 服务器端收到用户端浏览器发送的密钥X,使用私钥对其解密,就会得到客户端所生成的密钥X,然后就可以使用密钥X对数据进行加密操作,再将加密数据返回给浏览器。
- 浏览器收到服务器发来的加密数据,使用密钥X对其进行解密,就可拿到传输的数据。
加密方式
对称式加密
特点:
对称式加密,加密和解密使用的都是同一把密钥;
若密钥进行传输则容易泄露;
优缺点:运算速度快;无法安全地将密钥传输给通信方。
package com.ape.AES;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.naming.spi.DirStateFactory.Result;
public class AES_CBC {
//加密
public static String encryByCBC(String str,String key) {
String result="";
//将原始内容转换成byte[]
byte[] source = str.getBytes();
try {
//创建一个AES加密算法对象
//加密算法AES
//工作模式为CBC 每次加密结果不同
//填充模式PKCS5Padding
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//创建密钥
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
//16个字节的随机数组
SecureRandom random = SecureRandom.getInstanceStrong();
byte[] numArr = random.generateSeed(16);
System.out.println("CBC工作模式下产生的16个字节随机数:"+Arrays.toString(numArr));
IvParameterSpec iv = new IvParameterSpec(numArr);
//初始化
//参数一 操作模式:加密操作 ENCRYPT_MODE
//参数二 密钥
//参数三 16个字节随机数组
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec,iv);
//执行最终加密
byte[] mm = cipher.doFinal(source);
//合并数组
//随机数组+加密结果数组
byte[] addArr = addArr(numArr,mm);
//将结果使用Base64编码成字符串内容
result = Base64.getEncoder().encodeToString(addArr);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
//解密
public static String decryByCBC(String str,String key) {
//按照Base64解码
byte[] source = Base64.getDecoder().decode(str);
//拆解出"随机数组"
byte[] arr = new byte[16];
System.arraycopy(source, 0, arr, 0, 16);
System.out.println("CBC工作模式下拆解的16个字节随机数:"+Arrays.toString(arr));
//拆解出"加密后的数组"
byte[] newarr = new byte[source.length-arr.length];
System.arraycopy(source, arr.length, newarr, 0, newarr.length);
String result="";
try {
//创建一个AES加密算法对象
//加密算法AES
//工作模式为CBC 每次加密结果不同
//填充模式PKCS5Padding
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//创建密钥
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
//创建参数对象
IvParameterSpec iv = new IvParameterSpec(arr);
//初始化
//参数一 操作模式:解密操作 DECRYPT_MODE
//参数二 密钥
//参数三 16个字节随机数组
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec,iv);
//执行最终加密
byte[] mm = cipher.doFinal(newarr);
result = new String(mm);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
//数组合并
public static byte[] addArr(byte[] arr1,byte[] arr2) {
byte[] resultArr = new byte[arr1.length + arr2.length];
System.arraycopy(arr1, 0, resultArr, 0, arr1.length);
System.arraycopy(arr2, 0, resultArr, arr1.length, arr2.length);
return resultArr;
}
}
非对称式加密
特点:
非对称式加密,加密使用公钥加密,解密使用私钥解密;
公钥可对外公开,私钥仅自己知道;
优缺点:可以更安全地将公开密钥传输给通信发送方;运算速度慢。
package com.ape.RSA;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
//非对称式加密:RSA算法
public class RSA {
//私钥
PrivateKey sk;
//公钥
PublicKey pk;
public RSA() throws GeneralSecurityException {
//创建密钥对生成器
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
//初始化长度为1024字节
kpGen.initialize(1024);
//生成"密钥对"
KeyPair kp = kpGen.generateKeyPair();
//通过"密钥对" 分别获取公钥和私钥
this.sk = kp.getPrivate();
this.pk = kp.getPublic();
}
//把私钥导出为字节 方便查看
public byte[] getPrivateKey() {
return this.sk.getEncoded();
}
//把公钥导出为字节 方便查看
public byte[] getPublicKey() {
return this.pk.getEncoded();
}
/* 加密过程 */
//用公钥加密
public byte[] encrypt(byte[] message) throws GeneralSecurityException{
//创建RSA加密算法对象
Cipher cipher = Cipher.getInstance("RSA");
//初始化操作模式、公钥
cipher.init(Cipher.ENCRYPT_MODE, this.pk);
//执行最终操作
return cipher.doFinal(message);
}
//用私钥解密
public byte[] decrypt(byte[] message) throws GeneralSecurityException{
//创建RSA加密算法对象
Cipher cipher = Cipher.getInstance("RSA");
//初始化操作模式、公钥
cipher.init(Cipher.DECRYPT_MODE, this.sk);
//执行最终操作
return cipher.doFinal(message);
}
}