参考视频: https://www.bilibili.com/video/BV1tz4y197hm
package com.shi.encrypt.ascii;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.nio.charset.Charset;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* Ascii 编码测试
*
* @author shiye
* @create 2020-07-27 17:25
*/
public class AsciiDemo {
//每个字节数据再ASCII中都有一个数字对应
@Test
public void test1() {
// char a = 'A';
// int b = a;
// //65
// System.out.println(b);
String a = "AaZ";
char[] chars = a.toCharArray();
for (char aChar : chars) {
int asciiA = aChar;
System.out.println(asciiA);
}
}
/**
* 凯撒加密
* 就是移位法加密
* 破解方式:使用概率分析法:默认最高是e
*/
@Test
public void kaiserTest() {
//定义原文
String input = "Hello World";
//向右移动3位
int key = 3;
char[] chars = input.toCharArray();
//装新生成的数字
StringBuilder sb = new StringBuilder();
for (char aChar : chars) {
int b = aChar;
b = b + key;
char bChar = (char) b;
sb.append(bChar);
}
//加密后的密文为====Khoor#Zruog
System.out.println("加密后的密文为====" + sb.toString());
System.out.println("====================================");
char[] charArray = sb.toString().toCharArray();
StringBuilder tempA = new StringBuilder();
for (char charA : charArray) {
int c = charA;
c = c - key;
char charC = (char) c;
tempA.append(charC);
}
//解密后的明文====Hello World
System.out.println("解密后的明文====" + tempA);
}
/**
* 根据编码格式不一样,对应的字节也不一样
* 如果是UTF-8: 一个中文对应的是三个字节: -26 -106 -67
* 如果是GBK: 一个中文对应俩个字节:-54 -87
* 如果是英文就无所谓编码格式
*
* @throws Exception
*/
@Test
public void test2() throws Exception {
String a = "施";
byte[] aBytes = a.getBytes("GBK");
for (byte abyte : aBytes) {
System.out.println(abyte);
}
}
/**
* 对称加密:DES加密 密钥必须是8位
* 如果是使用AES进行加密的,需要密码是16位
* 需要配合base64使用
* <p>
* 加密算法/加密模式/填充模式
* DES
* DES/ECB/PKCS5Padding 默认方式
* DES/ECB/NoPadding
* DES/CBC/PKCS5Padding
* DES/CBC/NoPadding
* <p>
* AES
* AES/ECB/PKCS5Padding 默认方式
* AES/ECB/NoPadding
* AES/CBC/PKCS5Padding
* AES/CBC/NoPadding
*/
@Test
public void testDES() throws Exception {
//原文
String input = "施爷";
System.out.println("明文==" + input);
//定义key,密钥必须是8位
String key = "12345678";
//算法
String transformation = "DES";
// String transformation = "DES/ECB/PKCS5Padding";
// String transformation = "DES/CBC/PKCS5Padding";
//再使用CBC加密模式的时候需要使用该iv变量,IV必须是8个字节
// IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
//如果是使用AES进行加密的,需要密码是16位
// String transformation = "AES";
//创建加密对象
Cipher cipher = Cipher.getInstance(transformation);
//加密类型
String algorithm = "DES";
/**
* 创建加密规则
* 第一参数: 表示key的字节
* 第二个参数:表示加密的类型
*/
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
/**
* 进行加密初始化
* 第一个表示模式,加密模式,解密模式
* 第二个参数表示:加密的规则
*/
// cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec,iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
/**
* 调用加密方法
* 参数表示原文的字节数组
*/
byte[] bytes = cipher.doFinal(input.getBytes());
// for (byte aByte : bytes) {
// System.out.println(aByte);
// }
// System.out.println(new String(bytes));//a&f�B
/**
* 需要配合base64进行加密,否则会出现乱码
* 如果字节不够3个使用=号补齐
*/
String encode = Base64.encode(bytes);
System.out.println("加密==" + encode);//DmEmZoQXQhI=
System.out.println("***************解密*******************");
//创建解密对象
Cipher cipher1 = Cipher.getInstance(transformation);
/**
* 创建解密规则
* 第一参数: 表示key的字节
* 第二个参数:表示解密的类型
*/
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
//解密对象初始化
cipher1.init(Cipher.DECRYPT_MODE, sks);
//解码
byte[] decode = Base64.decode(encode);
//解密
byte[] bytes1 = cipher1.doFinal(decode);
System.out.println("解密==" + new String(bytes1));
}
/**
* Base64位测试,
* 原理:三个字节位一组,总共24位,把24位拆成4组,每组6个字节,高位补齐2个字节0
* 根据base64位编码表进行编排,生成信的字符串,
* 不足三个字节的使用=号补齐
*/
@Test
public void base64Test() throws Exception {
System.out.println(Base64.encode("1".getBytes()));//MQ==
System.out.println(Base64.encode("12".getBytes()));//MTI=
System.out.println(Base64.encode("123".getBytes()));//MTIz
//汉字utf-8编码,就是三个字节
System.out.println(Base64.encode("施".getBytes()));//5pa9
//如果是使用GBK编码就是俩个字节
System.out.println(Base64.encode("施".getBytes("GBK")));//yqk=
}
/**
* 消息摘要/数字摘要
* 算法:MD5
* SHA-1
* SHA-256
* SHA-512
*/
@Test
public void messageDigest() throws NoSuchAlgorithmException {
//原文
String input = "施爷";
//算法
String algorithm = "MD5";
//创建消息摘要对象
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
//执行消息摘要进行加密
byte[] digest = messageDigest.digest(input.getBytes());
//使用base64进行转码
System.out.println("Base64编码后的值为:" + Base64.encode(digest));//AsK7qXM7045eqFc2jILPBw==
//===================================
//直接转成16进制输出结果
for (byte b : digest) {
//把密文转成16进制
String hexString = Integer.toHexString(b & 0Xff);
if (hexString.length() == 1) {
hexString = "0" + hexString;
}
System.out.print(hexString);
}
}
/**
* 非对称加密:RSA ECC
* RSA 加密算法
* 想单独生成 PrivateKey 对象 可以使用 KeyFactory
* PublicKey 同上
*/
@Test
public void RSAtest() throws Exception {
String input = "施爷";
//使用的加密算法
String algorithm = "RSA";
//KeyPairGenerator:密钥对生成器对象
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
//生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//===私钥
PrivateKey aPrivate = keyPair.getPrivate();
byte[] encoded = aPrivate.getEncoded();
String privateKey = Base64.encode(encoded);
System.out.println("私钥为==" + privateKey);
FileUtils.writeStringToFile(new File("privateKey.pub"), privateKey, Charset.forName("UTF-8"));
//===公钥
PublicKey aPublic = keyPair.getPublic();
byte[] encoded1 = aPublic.getEncoded();
String publicKey = Base64.encode(encoded1);
System.out.println("公钥为==" + publicKey);
FileUtils.writeStringToFile(new File("publicKey.pri"), publicKey, Charset.forName("UTF-8"));
/*======================使用私钥加密======================*/
//创建加密对象
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, aPrivate);
byte[] doFinal = cipher.doFinal(input.getBytes());
String encode = Base64.encode(doFinal);
System.out.println("加密后的值为===" + encode);
/*======================使用公钥解密======================*/
Cipher cipher2 = Cipher.getInstance(algorithm);
cipher2.init(Cipher.DECRYPT_MODE, aPublic);
byte[] doFinal2 = cipher2.doFinal(Base64.decode(encode));
System.out.println("解密后的值为===" + new String(doFinal2));
}
/**
* 数字证书
*/
@Test
public void test22() throws Exception {
String input = "施爷";
//使用的加密算法
String algorithm = "RSA";
String privateKeyStr = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKdzMj8aAS28BIH6qGIB7+O0z6bu\n" +
"ujjYJlBhFbtt+Ai9Mm90+rQq7cnc0g7FGAGsBvtfoF+BEKLUNMl6LkGsXM8Sz42P+UWQGslhWYqW\n" +
"Wo4f7PyCVNlLEcsRgt43JnFQ1yUbtttMKHs8whYcAgFaIyEdGw4h8aGffEVA0VxkshCHAgMBAAEC\n" +
"gYBOyOmEPQT+8q6gRUJCUqz+0wy8eygNJM3qFbO26we/fN0lCcIHUQduacI/hsZDyx/B1/1J0hz0\n" +
"r6lifmUTKzjCxKvxpvQFa0iM3njqNX/z+tOpK9RX+awIW7syACbZG4ZCwCPSflB/3uoBYHT4oY5/\n" +
"WumWX1Berb8WUU1jHZ8SYQJBAOsbXsh4IubAdzmerYoKh5RWEwxF6nHd58XRQq6DnKWvRN/LNUsF\n" +
"fTDodFkhpC2VFSMxaNSelboYRvXON59rWzECQQC2VKVgu8moqfrS11fEwQ6Iq4sG+mt08/GT2BUZ\n" +
"yz5z6vXCK+cTjRf4hgR4oGC01/ZlL8OhiUsgA8cprmHoiMk3AkA5/1N/cptxfxMqRKmcvwI5Jo6m\n" +
"XWz7T/mIBBpGALOY78a2ymNIMX9znDRvdGwSzo8bUmoA4WogMTL4GjoAerRRAkAksXI6vm/97n9Y\n" +
"0ReLtCJ9pLAs7laTycgTLchJUZq271EYC4fManepfycFM5liq5edk3g2WQ/yWHBLVhnEF0sPAkA7\n" +
"B/cOKB4Z0HkUSMEL0P8OT7N/afZMzv/KjpTAMKUfrgNptSTG5y2TcGEv4Bktj/+4SAegnVKF98oM\n" +
"+Vh4i9lw";
String publiceKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnczI/GgEtvASB+qhiAe/jtM+m7ro42CZQYRW7\n" +
"bfgIvTJvdPq0Ku3J3NIOxRgBrAb7X6BfgRCi1DTJei5BrFzPEs+Nj/lFkBrJYVmKllqOH+z8glTZ\n" +
"SxHLEYLeNyZxUNclG7bbTCh7PMIWHAIBWiMhHRsOIfGhn3xFQNFcZLIQhwIDAQAB";
//创建key工厂
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
/*===========================生成私钥对象===========================*/
//私钥规则
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyStr));
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// System.out.println("私钥对象=" + privateKey);
/*===========================生成公钥对象===========================*/
//公钥规则
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publiceKeyStr));
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
// System.out.println("公钥对象=" + publicKey);
/*------------------------生成数字签名------------------------------*/
//获取签名对象
Signature signature = Signature.getInstance("sha256withrsa");
//初始化签名
signature.initSign(privateKey);
//传入原文
signature.update(input.getBytes());
//开始签名
byte[] sign = signature.sign();
String encode_sign = Base64.encode(sign);
System.out.println("生成的签名为=" + encode_sign);
/*------------------------校验数字签名------------------------------*/
//获取签名对象
Signature signature2 = Signature.getInstance("sha256withrsa");
//初始化校验
signature2.initVerify(publicKey);
//传入原文
signature2.update(input.getBytes());
//开始和签名对比,校验签名
boolean verify = signature2.verify(Base64.decode(encode_sign));
System.out.println("验签的结果为=" + verify);
}
}