前言
在HFUT_qianyang的基础上,去除了apache库的依赖。
所作工作主要有:
- 用自带的
java.util.Base64
包处理base64编码; - 实现byteToHexString和HexToByte两个编码小工具,(见本文最后部分);
- 解决AES加密中报BadpaddingException错的问题参考;
BASE64
import java.util.Base64;
class BASE64 {
public static void main(String[] args) throws Exception{
String str = "hello";
String base = Base64.getEncoder().encodeToString(str.getBytes("UTF-8"));
System.out.println(base);
System.out.println(new String(Base64.getDecoder().decode(base)));
}
}
SHA
常见
散列函数
import java.security.MessageDigest;
public class SHAEncrypt {
public static String encrypt(byte[] bytes) throws Exception{
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
byte[] resultBytes = messageDigest.digest(bytes);
// return Hex.encodeHexString(resultBytes);
return bytesToHexString(resultBytes);
}
public static final String bytesToHexString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = 0; i < bArray.length; i++) {
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}
public static void main(String[] args) throws Exception{
System.out.println(SHAEncrypt.encrypt("helloworld".getBytes("UTF-8")));
}
}
AES
常见
对称加密
算法
import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class AESEncrypt {
public static void main(String[] args) {
String message = "hello world";
String output = doAES(message,KEY, Cipher.ENCRYPT_MODE);
System.out.println("加密后"+output);
System.out.println("解密后"+doAES(output,KEY,Cipher.DECRYPT_MODE));
}
// 自定义密钥
private static final String KEY = "csust";
private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
private static String doAES(String message,String key, int mode){
try {
if (message.isEmpty() || key.isEmpty()){
return null;
}
// 由于AES算法要求密钥的长度为16的倍数,(1,2,3,4)步的目的: 把用户自定义的密钥替换成16位的密钥
// 1. 构造密钥生成器,指定为AES算法
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
// 2. 根据用户自定义密钥对应的字节数组,生成一个128位的随机源(只能是128 or 192 or 256中的一个)
// !! 此处创建了 Random 实例
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG") ;
secureRandom.setSeed(key.getBytes("utf-8"));
keyGenerator.init(128, secureRandom);
// 3. 生成AES算法的原始对称密钥
SecretKey secretKey = keyGenerator.generateKey();
// 4. 获取原始对称密钥的字节数组
byte[] enCodeFormat = secretKey.getEncoded();
// 5. 根据字节数组生成AES密钥
SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat,"AES");
// 6.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(mode, secretKeySpec);
if (mode == Cipher.ENCRYPT_MODE) {
byte[] content = message.getBytes();
byte[] result = cipher.doFinal(content);
// !!! 加密,AES加密后的结果默认是Base64格式的字节数组
return Base64.getEncoder().encodeToString(result);
} else {
byte[] content = Base64.getDecoder().decode(message);
byte[] result = cipher.doFinal(content);
return new String(result);
}
} catch (Exception e) {
// NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException | InvalidKeyException
e.printStackTrace();
}
return null;
}
}
RSA
常见
非对称加密
import java.util.Base64;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSAEncrypt {
private static Map<Integer, String> keyMap = new HashMap<Integer, String>(); //用于封装随机产生的公钥与私钥
public static void main(String[] args) throws Exception {
//生成公钥和私钥
genKeyPair();
//加密字符串
String message = "hello world";
System.out.println("随机生成的公钥为:" + keyMap.get(0));
System.out.println("随机生成的私钥为:" + keyMap.get(1));
String messageEn = encrypt(message,keyMap.get(0));
System.out.println("加密后的字符串为:" + messageEn);
String messageDe = decrypt(messageEn,keyMap.get(1));
System.out.println("还原后的字符串为:" + messageDe);
}
/**
* 随机生成密钥对
* @throws NoSuchAlgorithmException
*/
public static void genKeyPair() throws NoSuchAlgorithmException {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024,new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥
String publicKeyString = new String(Base64.getEncoder().encodeToString(publicKey.getEncoded()));
// 得到私钥字符串
String privateKeyString = new String(Base64.getEncoder().encodeToString((privateKey.getEncoded())));
// 将公钥和私钥保存到Map
keyMap.put(0,publicKeyString); //0表示公钥
keyMap.put(1,privateKeyString); //1表示私钥
}
/**
* RSA公钥加密
*
* @param str
* 加密字符串
* @param publicKey
* 公钥
* @return 密文
* @throws Exception
* 加密过程中的异常信息
*/
public static String encrypt( String str, String publicKey ) throws Exception{
//base64编码的公钥
byte[] decoded = Base64.getDecoder().decode(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = Base64.getEncoder().encodeToString((cipher.doFinal(str.getBytes("UTF-8"))));
return outStr;
}
/**
* RSA私钥解密
*
* @param str
* 加密字符串
* @param privateKey
* 私钥
* @return 铭文
* @throws Exception
* 解密过程中的异常信息
*/
public static String decrypt(String str, String privateKey) throws Exception{
//64位解码加密后的字符串
byte[] inputByte = Base64.getDecoder().decode(str.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.getDecoder().decode(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
}
byteToHexstring
实现 字节码 与 十六进制字符 的互相转换
class hexByteUtil{
public static void main(String[] args) throws Exception{
String oriStr = "hello world";
System.out.println("originalStr:"+oriStr);
byte bts[] = oriStr.getBytes();
System.out.println("getBytes: " + bts);
String str = bytesToHexString(bts);
System.out.println("byteToHex: " + str);
byte bs[] = hexToBytes(str);
System.out.println("HexToByte-(newString): "+new String(bs));
}
public static final String bytesToHexString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = 0; i < bArray.length; i++) {
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}
public static final byte[] hexToBytes(String str){
byte bs[] = new byte[str.length()];
for (int i= 0;i<str.length();i+=2) {
StringBuffer sb = new StringBuffer(str);
String c = sb.substring(i,i+2);
bs[i] = Byte.parseByte(c, 16);
}
return bs;
}
}