package test.projectTest;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.UUID;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
import org.junit.Test;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
public class EncryptTest {
/**
* Base64算法:将对应字符ASCII字符二进制编码用Base64索引代替,3个ASCII字符刚好对应4个Base64字符
* https://blog.csdn.net/qq_20545367/article/details/79538530
*/
@Test
public void base64Test(){
String riginal = "Sun";
byte[] bytes = riginal.getBytes();
// 转换成Base64字符
String enBase64Str = Base64.encode(bytes);
System.out.println(enBase64Str);
// Base64字符转换成ASCCII字符
String deBase64Str = new String(Base64.decode(enBase64Str));
System.out.println(deBase64Str);
}
/**
* MD5加密,md5为不可逆算法,密文对应多个明文
* @throws NoSuchAlgorithmException
*/
@Test
public void md5Test() throws NoSuchAlgorithmException{
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
MessageDigest digest = MessageDigest.getInstance("MD5");
String riginal = "Aa123456";
byte[] bytes = riginal.getBytes();
digest.reset();
digest.update(bytes);
bytes = digest.digest();
System.out.println("commons-codec.jar包处理转换成十六进制"+Hex.encodeHexString(bytes).toUpperCase());
// 把密文转换成十六进制的字符串形式(方法一)
int j = bytes.length;
char stra[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = bytes[i];
stra[k++] = hexDigits[byte0 >>> 4 & 0xf];
stra[k++] = hexDigits[byte0 & 0xf];
}
String enStr = new String(stra);
System.out.println("MD5加密(方法1)"+enStr);
// 把密文转换成十六进制的字符串形式(方法二)
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++)
{
int t = bytes[i];
//Integer方式转成16进制字符
sb.append(Integer.toString(t >> 4 & 0xF, 16)).append(Integer.toString(t & 0xF, 16));
}
System.out.println("MD5加密(方法2)"+sb.toString().toUpperCase());
//数字十进制转成十六进制
System.out.println("数字十进制转成十六进制"+Integer.toString(80, 16));
}
/**
* SHA算法:安全散列算法,不可逆算法
* @throws NoSuchAlgorithmException
*/
@Test
public void shaTest() throws NoSuchAlgorithmException{
String src = "Aa123456";
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(src.getBytes());
System.out.println(Hex.encodeHexString(md.digest()));
}
/**
* UUID获取随机数
*/
@Test
public void uuidTest(){
//32位
String uuid = String.valueOf(UUID.randomUUID()).replace("-", "").toUpperCase();
System.out.println(uuid);
//64位
uuid += String.valueOf(UUID.randomUUID()).replace("-", "").toUpperCase();
System.out.println(uuid);
}
/**
* AES对称算法(优选对称算法)
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
*/
@Test
public void aesTest() throws Exception{
// Hashtable<String,String> map = new Hashtable<String,String>();
// map.put("1", "2");
//加密
String key = "sdfasff422asdfsaf5416541515g6gdasgfasda";//秘钥
String riginal = "Aa123456";//明文
byte[] bytes = riginal.getBytes();
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128,new SecureRandom(key.getBytes()));//初始化秘钥长度
SecretKey secretKey = keyGenerator.generateKey();
byte[] keyBytes = secretKey.getEncoded();
SecretKey generateKey = new SecretKeySpec(keyBytes,"AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, generateKey);
bytes = cipher.doFinal(bytes);
System.out.println("AES加密结果(转为16进制):"+Hex.encodeHexString(bytes));
String base64Bytes = new BASE64Encoder().encode(bytes);
System.out.println("AES加密结果(Base64处理):"+base64Bytes);
//解密
cipher.init(Cipher.DECRYPT_MODE, generateKey);
byte[] result = Hex.decodeHex(Hex.encodeHexString(bytes).toCharArray());
System.out.println("AES解密结果(转为16进制):"+new String(cipher.doFinal(result)));
result = new BASE64Decoder().decodeBuffer(base64Bytes);
System.out.println("AES解密结果(Base64处理):"+new String(cipher.doFinal(result)));
}
/**
* DES算法对称算法
* @throws Exception
*/
@Test
public void desTest() throws Exception{
String key = "sdfasff422asdfsaf5416541515g6gdasgfasda";//秘钥
String riginal = "Aa123456";//明文
byte[] bytes = riginal.getBytes();
KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
keyGenerator.init(56,new SecureRandom(key.getBytes()));//size
SecretKey secretKey = keyGenerator.generateKey();
byte[] keyBytes = secretKey.getEncoded();
DESKeySpec desKeySpec = new DESKeySpec(keyBytes);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
SecretKey generateKey = secretKeyFactory.generateSecret(desKeySpec);
//加密
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, generateKey);
byte[] resultBytes = cipher.doFinal(bytes);
System.out.println("DES加密:"+Hex.encodeHexString(resultBytes));
cipher.init(Cipher.DECRYPT_MODE, generateKey);
byte[] result = Hex.decodeHex(Hex.encodeHexString(resultBytes).toCharArray());
System.out.println("DES解密:"+new String(cipher.doFinal(result)));
}
/**
* RSA非对称算法
* @throws Exception
*/
@Test
public void rsaTest() throws Exception{
RSAPublicKey rsaPublicKey;//公钥
RSAPrivateKey rsaPrivateKey;//私钥
String riginal = "Aa123456";//明文
byte[] bytes = riginal.getBytes();
/***************************生成秘钥START***************************************/
// String key = "sdfasff422asdfsaf5416541515g6gdasgfasda";//秘钥种子
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512/*,new SecureRandom(key.getBytes())*/);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
String publicKeyStr = Hex.encodeHexString(rsaPublicKey.getEncoded());
String privateKeyStr = Hex.encodeHexString(rsaPrivateKey.getEncoded());
System.out.println("RSA公钥(转16进制):" + publicKeyStr);
System.out.println("RSA私钥(转16进制):" + privateKeyStr);
publicKeyStr = Base64.encode(rsaPublicKey.getEncoded());//公钥字符串
privateKeyStr = Base64.encode(rsaPrivateKey.getEncoded());//私钥字符串
System.out.println("RSA公钥(转base64):" + publicKeyStr);
System.out.println("RSA私钥(转base64):" + privateKeyStr);
/***************************生成秘钥END***************************************/
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Cipher cipher = Cipher.getInstance("RSA");
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyStr));
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);//私钥
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publicKeyStr));
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);//公钥
/***********************私钥加密 公钥解密start***********************************/
//加密
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] resultBytes = cipher.doFinal(bytes);
System.out.println("私钥加密 公钥解密》加密(转base64):"+Base64.encode(resultBytes));
//解密
cipher.init(Cipher.DECRYPT_MODE, publicKey);
resultBytes = cipher.doFinal(Base64.decode(Base64.encode(resultBytes)));
System.out.println("私钥加密 公钥解密》解密(转base64):"+new String(resultBytes));
/***********************私钥加密 公钥解密end***********************************/
/***********************私钥解密 公钥加密start***********************************/
//加密
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
resultBytes = cipher.doFinal(bytes);
System.out.println("私钥解密 公钥加密》加密(转16进制):"+Hex.encodeHexString(resultBytes));
//解密
cipher.init(Cipher.DECRYPT_MODE, privateKey);
resultBytes = cipher.doFinal(Hex.decodeHex(Hex.encodeHexString(resultBytes).toCharArray()));
System.out.println("私钥解密 公钥加密》解密(转16进制):"+new String(resultBytes));
/***********************私钥解密 公钥加密end***********************************/
}
/**
* 数字签名(非对称加密已经灰常安全了,但是还有一个破绽:
服务器A公布了自己的公钥,我的电脑是用服务器A的公钥加密数据后再发给服务器A的;这时候服务器B侵入了我的电脑,
把我用来加密的公钥换成了它的公钥,于是我发出去的数据就会被服务器B的私钥破解了。肿么防止公钥被篡改呢?
对,我们想到了前面的消息摘要,服务器A把公钥丢给我的时候,同时去CA申请一份数字证书,其实主要就是公钥的消息摘要,
有了这份证书,当我再用公钥加密的时候,我就可以先验证一下当前的公钥是否确定是服务器A发送给我的。 )
* @throws Exception
*/
@Test
public void rsaSign() throws Exception{
String riginal = "Aa123456";//明文
byte[] bytes = riginal.getBytes();
/***************************生成秘钥START***************************************/
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
PrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
String publicKeyStr = Hex.encodeHexString(rsaPublicKey.getEncoded());
String privateKeyStr = Hex.encodeHexString(rsaPrivateKey.getEncoded());
System.out.println("RSA公钥(转16进制):" + publicKeyStr);
System.out.println("RSA私钥(转16进制):" + privateKeyStr);
publicKeyStr = Base64.encode(rsaPublicKey.getEncoded());//公钥字符串
privateKeyStr = Base64.encode(rsaPrivateKey.getEncoded());//私钥字符串
System.out.println("RSA公钥(转base64):" + publicKeyStr);
System.out.println("RSA私钥(转base64):" + privateKeyStr);
/***************************生成秘钥END***************************************/
/***************************签名START***************************************/
PKCS8EncodedKeySpec pkcs8EncodedKeySpec
= new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(bytes);
//生成签名bytes
byte[] signBytes = signature.sign();
System.out.println("明文签名结果:"+Base64.encode(signBytes));
/***************************签名START***************************************/
/***************************验证签名START***************************************/
X509EncodedKeySpec x509EncodedKeySpec =
new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
signature = Signature.getInstance("MD5withRSA");
signature.initVerify(publicKey);
signature.update(bytes);
boolean isVerified = signature.verify(signBytes);
System.out.println(isVerified);
/***************************验证签名START***************************************/
}
}