java加解密

文章目录

  • java的加密与解密技术:
  • 编码
    • Base64
      • org.apache.commons.codec.binary.Base64
      • jdk自带Base64
    • org.apache.commons.codec.binary.Hex
  • 加\解密
    • MD5(单向加密算法)
      • org.apache.commons.codec.digest.DigestUtils
      • jdk自带Hex
    • SHA(单向加密算法)
      • org.apache.commons.codec.digest.DigestUtil
      • jdk自带Sha
    • DES(对称加密算法)
    • AES(对称加密算法)建议使用
    • PBE(对称加密算法)基于口令
    • RSA(非对称加密算法)

参考文献:
https://www.runoob.com/java/java8-base64.html
加密篇之一 - 对称加密算法 DES,AES,PBE
Apache Commons Codec – 加密与编码
SHA算法系列介绍
java 编码:
伪加密,实质是做编码

  • base64
  • hex

java的加密与解密技术:

  • 单向加密算法:以MD5 SHA算法为代表
  • 对称加密算法:以DES 三重DES AES PBE算法为代表
  • 非对称加密算法:以RSA为代表

简要的说下这三种加密算法的区别

  • 单向加密算法,它不会有密钥,因为它是单向的,加密之后无法解密,主要用处是数据完整性的验证。
  • 对称加密算法,其特征是公钥与私钥相同。一般用来数据储存,比如将数据加密之后存入数据库,那么数据库管理员就无法泄密数据库中的类容,有密钥的人却可以根据密钥解密数据库中的真正数据。
  • 非对称加密算法,就是公钥与私钥不同,一般公钥公开,私钥在你想给人看到数据的人的手上,利用私钥来解密数据。它一般是用于数据传输的加密。

编码

Base64

Base64能将数据转为8个字节,每6比特转成一位64进制数,利于网络传输
经Base64编码后的字符串的字符数是以4为单位的整数倍

org.apache.commons.codec.binary.Base64

String content = "AaBb我在测试";
Base64 base64 =  new Base64();
String encodeStr = base64.encodeToString(content.getBytes("UTF-8"));
System.out.println(encodeStr);
byte[] decodeArr = base64.decode(encodeStr.getBytes("UTF-8"));
String decodeStr = new String(decodeArr);
System.out.println(decodeStr);

jdk自带Base64

Base64工具类提供了一套静态方法获取下面三种BASE64编解码器:

  1. 基本:输出被映射到一组字符A-Za-z0-9+/,编码不添加任何行标,输出的解码仅支持A-Za-z0-9+/。
  2. URL:输出映射到一组字符A-Za-z0-9+_,UrlBase64 就是专门为URL参数加密而设计的,将字符映射表中用作补位的"=“换成”." 并用"-“代替”+" 用"_“代替”/"。
  3. MIME:输出隐射到MIME友好格式。输出每行不超过76字符,并且使用’\r’并跟随’\n’作为分割。编码输出最后没有行分割。

详情参看:https://www.runoob.com/java/java8-base64.html

//=============jdk自带的1============
BASE64Encoder encoder = new BASE64Encoder();
String enStr = encoder.encode("原文".getBytes());
// 去掉可能有的换行符
enStr = enStr.replaceAll("[\\s*\t\n\r]", "");
System.out.println(enStr);
BASE64Decoder decoder = new BASE64Decoder();
System.out.println(new String(decoder.decodeBuffer(enStr)));

//=============jdk自带的2============
String base64encodedString = java.util.Base64.getEncoder().encodeToString("runoob?java8".getBytes("utf-8"));
System.out.println("Base64 编码字符串 (基本) :" + base64encodedString);
byte[] base64decodedBytes = java.util.Base64.getDecoder().decode(base64encodedString);
System.out.println("原始字符串: " + new String(base64decodedBytes, "utf-8"));

org.apache.commons.codec.binary.Hex

十六进制转换,将语句转出十六进制

String content = "AaBb我在测试hex";
String encodeHexString = Hex.encodeHexString(content.getBytes("UTF-8"));
System.out.println(encodeHexString.length());
//先转换成char数组,第二个参数意思是是否全部转换成小写
char[] encodeHexArr = Hex.encodeHex(content.getBytes("UTF-8"), true);
System.out.println(new String(encodeHexArr));

byte[] decodeHexArr = Hex.decodeHex(encodeHexString);
System.out.println(new String(decodeHexArr));
byte[] decodeHexArr1 = Hex.decodeHex(encodeHexArr);
System.out.println(new String(decodeHexArr1));

加\解密

MD5(单向加密算法)

应用:用户密码加密

org.apache.commons.codec.digest.DigestUtils

String content = "AaBb我在测试hex";
String md5 = DigestUtils.md5Hex(content.getBytes("UTF-8"));
System.out.println(md5);

jdk自带Hex

MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5Bytes = md.digest("原文".getBytes());
System.out.println(Hex.encodeHex(md5Bytes));

SHA(单向加密算法)

SHA-1(160比特)、SHA2(SHA-256、SHA-384、SHA-512)
应用:数字签名

org.apache.commons.codec.digest.DigestUtil

String content = "AaBb我在测试hex";
String sha1Hex = DigestUtils.sha1Hex(content.getBytes("UTF-8"));
System.out.println(sha1Hex);
System.out.println( DigestUtils.sha256Hex("原文"));

jdk自带Sha

MessageDigest md = MessageDigest.getInstance("SHA-256");  
byte[] md5Bytes = md.digest("原文".getBytes());
System.out.println(Hex.encodeHex(md5Bytes));

DES(对称加密算法)

// 设置秘钥,长度不能够小于8位,否则报错
String password = “12345678”;
DESKeySpec dks = new DESKeySpec(password.getBytes(“utf-8”));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(“DES”);
SecretKey key = keyFactory.generateSecret(dks);

Cipher cipher = Cipher.getInstance(“DES/CBC/PKCS5Padding”);
//偏移量,必须是8位,否则报错
IvParameterSpec iv = new IvParameterSpec(“12345678”.getBytes(“utf-8”));

//加密
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] bytes = cipher.doFinal(“原文”.getBytes(“utf-8”));
String pssd = new String(Base64.getEncoder().encode(bytes));
System.out.println(pssd);

// 解密
BASE64Decoder decoder = new BASE64Decoder();
System.out.println(new String(cipher.doFinal(decoder.decodeBuffer(pssd)), “utf-8”));

}

AES(对称加密算法)建议使用

用来替代DES,效率更高

//指定秘钥,默认是随机秘钥
String password="key";
// 创建AES的Key生产者
KeyGenerator kg = KeyGenerator.getInstance("AES");
// 确定密钥长度
kg.init(128, new SecureRandom(password.getBytes()));
byte[] keyBytes = kg.generateKey().getEncoded();
// 转换为AES专用密钥
Key key = new SecretKeySpec(keyBytes, "AES");
// 生成创建密码器
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

// 进入加密模式
cipher.init(Cipher.ENCRYPT_MODE, key);
// 加密
byte[] result = cipher.doFinal("原文".getBytes());
// 不进行Base64编码的话,那么这个字节数组对应的字符串就是乱码
System.out.println(Base64.encodeBase64String(result));

// 进入解密模式
cipher.init(Cipher.DECRYPT_MODE, key);
// 解密
System.out.println(new String(cipher.doFinal(result)));

PBE(对称加密算法)基于口令

1.口令容易破解,所以要加“盐” 2.密匙 = 盐 + 口令

// 口令
String pwd = "token";
// 密钥格式化
PBEKeySpec keySpec = new PBEKeySpec(pwd.toCharArray());
// 密钥工厂
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
Key key = factory.generateSecret(keySpec);
// 强随机数生成器
SecureRandom random = new SecureRandom();
// 盐
byte[] salt = random.generateSeed(8);
// PBE参数格式化
PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, 100);
// 确定算法
Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");

// 进入加密模式,加入了口令 和 盐
cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
byte[] result = cipher.doFinal("原文".getBytes());
System.out.println(Base64.encodeBase64String(result));

// 进入解密模式
cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
System.out.println(new String(cipher.doFinal(result))); 

RSA(非对称加密算法)

私钥加密,公钥解密
公钥加密, 私钥解密

// 生成密钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//公钥
RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
// 私钥
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
// 格式化私钥
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

Cipher cipher = Cipher.getInstance("RSA");  // 确定算法
cipher.init(Cipher.ENCRYPT_MODE, privateKey);  // 确定加密密钥
byte[] result = cipher.doFinal("原文".getBytes());  // 加密
System.out.println(Base64.encodeBase64String(result));

// 格式化公钥
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

cipher = Cipher.getInstance("RSA"); // 确定算法
cipher.init(Cipher.DECRYPT_MODE, publicKey);  // 确定公钥
System.out.println(new String(cipher.doFinal(result))); // 解密

你可能感兴趣的:(java基础,apache)