浅谈几种常见的加密算法

文章目录

  • 一、编码格式 (这个按道理来讲是算不上加密的,但是比较常用)
  • 二、消息摘要算法 (这个按道理来讲是算不上加密的,但是比较常用)
  • 三、对称加密
  • 四、非对称加密
  • 在线加密测试工具
  • 参考相关文章

下面所有代码都是基于 jdk8

所有基于Apache的实现都需要引入下面这个包:



<dependency>
    <groupId>commons-codecgroupId>
    <artifactId>commons-codecartifactId>
    <version>1.11version>
dependency>

一、编码格式 (这个按道理来讲是算不上加密的,但是比较常用)

编码格式算法

二、消息摘要算法 (这个按道理来讲是算不上加密的,但是比较常用)

消息摘要算法

基于上面的 编码格式算法消息摘要算法 写了一个基础加密工具,对称加密非对称加密有单独的工具类,往下看就知道了。

package com.blog.www.util.coder.base;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.springframework.util.Base64Utils;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;
import java.util.Random;

/**
 * 基础编码工具类
 * 
* 包含以下几种加密: *
    *
  • Base64
  • *
  • URLEncoder、URLDecoder
  • *
  • MD5
  • *
  • MD5加随机盐
  • *
  • SHA
  • *
  • MAC
  • *
*

* 注意:
* Base64加密可逆,一般用来编码信息发送,甚至可以把图片转换成字符串发送到前端显示。注意不要用来发送机密信息!
* MD5、SHA、MAC这三种加密算法,是不可逆加密,我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。 *

* 创建人:leigq
* 创建时间:2017年10月23日 下午10:39:06
*/ @Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class BaseCoderUtils { /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ BASE64 编码、解码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */ /** * BASE64加密 *
* * @param binaryData 待加密二进制数据 * @return 加密后字符串 */
public static String encryptBase64(final byte[] binaryData) { // 安卓自带实现,因为安卓用不了Apache的实现,所以只能用自带的实现。注意,Base64.CRLF才对应Apache的默认模式! // return Base64.encodeToString(key, Base64.CRLF); return Base64Utils.encodeToString(binaryData); } /** * BASE64解密 *
* * @param base64String 加密后字符串 * @return 原始二进制数据 */
public static byte[] decryptBase64(final String base64String) { // 安卓自带实现 // return Base64.decode(key, Base64.CRLF); return Base64Utils.decodeFromString(base64String); } /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ BASE64 编码、解码 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */ /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ URL 编码、解码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */ /** * 将 URL 编码 */ public static String encodeURL(final String data) { String target; try { target = URLEncoder.encode(data, StandardCharsets.UTF_8.name()); } catch (Exception e) { log.error("编码出错!", e); throw new RuntimeException(e); } return target; } /** * 将 URL 解码 */ public static String decodeURL(final String data) { String target; try { target = URLDecoder.decode(data, StandardCharsets.UTF_8.name()); } catch (Exception e) { log.error("解码出错!", e); throw new RuntimeException(e); } return target; } /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ URL 编码、解码 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */ /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ MD5加密相关 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */ /** * MD5加密 * * @param data * @return 大写 */ public static String encryptMD5(final byte[] data) { return DigestUtils.md5Hex(data).toUpperCase(); } /** * MD5加密,字符串到字符串 * * @param data * @return 大写 */ public static String encryptMD5(final String data) { return encryptMD5(data.getBytes()); } /** * 3次MD5加密,字符串到字符串 * * @param data * @return 大写 */ public static String encryptTriMD5(final String data) { int count = 3; String md5 = data; for (int i = 0; i < count; i++) { md5 = encryptMD5(md5); } return md5; } /** * 生成含有随机盐的加密字符串 * * @param data 待加密的字符 * @return 加密后的字符(含 16 位随机盐),大写 */ public static String encryptMD5WithRandomSalt(final String data) { return encryptMd5WithRandomSalt(data); } /** * 校验密码是否正确 * * @param data 待验证的字符(明文) * @param md5StringWithSalt 加密后的字符(含 16 位随机盐) * @return 验证结果 */ public static boolean verifyMD5WithRandomSalt(final String data, final String md5StringWithSalt) { return verifyMd5WithRandomSalt(data, md5StringWithSalt); } /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ MD5加密相关 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */ /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ SHA 加密 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */ /** * 默认使用 SHA-1 20字节 160位 * 其他还有: * SHA-224 32字节 224位 * SHA-256 32字节 256位 * SHA-384 48字节 384位 * SHA-512 64字节 512位 * 由于它产生的数据摘要的长度更长,因此更难以发生碰撞,因此较之MD5更为安全,它是未来数据摘要算法的发展方向。 * 由于SHA系列算法的数据摘要长度较长,因此其运算速度与MD5相比,也相对较慢。 */ /** * SHA 加密 * * @param data * @return */ public static String encryptSHA(final byte[] data) { return DigestUtils.sha1Hex(data).toUpperCase(); } /** * SHA 加密,字符串到字符串
*
* * @param data * @return */
public static String encryptSHA(final String data) { return DigestUtils.sha1Hex(data).toUpperCase(); } /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ SHA 加密 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */ /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ MAC加密相关 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */ /** * 默认使用 HmacMD5 加密。 * 其他还有: * HmacSHA1 * HmacSHA256 * HmacSHA384 * HmacSHA512 */ /** * 初始化 MAC 密钥 * * @return MAC 密钥 * @throws NoSuchAlgorithmException */ public static String initMacKey() throws NoSuchAlgorithmException { KeyGenerator keyGenerator = KeyGenerator.getInstance(HmacAlgorithms.HMAC_MD5.getName()); SecretKey secretKey = keyGenerator.generateKey(); return encryptBase64(secretKey.getEncoded()); } /** * MAC 加密 * * @param data 待加密数据 * @param key 密钥,可用 initMacKey() 方法生成,也可自定义 * @return 加密后数据 */ public static String encryptHMAC(final byte[] data, final String key) { HmacUtils hmacMd5 = new HmacUtils(HmacAlgorithms.HMAC_MD5, key); return hmacMd5.hmacHex(data).toUpperCase(); } /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ MAC加密相关 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */ /** * 生成含有随机盐的加密字符串 * * @param data 待加密的字符 * @return 加密后的字符(含 16 位随机盐),大写 */ private static String encryptMd5WithRandomSalt(String data) { Random r = new Random(); StringBuilder sb = new StringBuilder(16); sb.append(r.nextInt(99999999)) .append(r.nextInt(99999999)); int len = sb.length(); if (len < 16) { for (int i = 0; i < 16 - len; i++) { sb.append("0"); } } String salt = sb.toString(); String md5WithSaltStr = DigestUtils.md5Hex(data + salt); char[] cs = new char[48]; for (int i = 0; i < 48; i += 3) { cs[i] = md5WithSaltStr.charAt(i / 3 * 2); char c = salt.charAt(i / 3); cs[i + 1] = c; cs[i + 2] = md5WithSaltStr.charAt(i / 3 * 2 + 1); } return new String(cs).toUpperCase(); } /** * 校验密码是否正确 * * @param data 待验证的字符(明文) * @param md5StrContainRandomSalt 加密后的字符(含 16 位随机盐) * @return 验证结果 */ private static boolean verifyMd5WithRandomSalt(String data, String md5StrContainRandomSalt) { // 32 位加密字符(不含盐) char[] cs1 = new char[32]; // 16 位的随机盐 char[] cs2 = new char[16]; for (int i = 0; i < 48; i += 3) { cs1[i / 3 * 2] = md5StrContainRandomSalt.charAt(i); cs1[i / 3 * 2 + 1] = md5StrContainRandomSalt.charAt(i + 2); cs2[i / 3] = md5StrContainRandomSalt.charAt(i + 1); } String salt = new String(cs2); return Objects.equals(DigestUtils.md5Hex(data + salt).toUpperCase(), new String(cs1)); } }

三、对称加密

对称加密

四、非对称加密

先来看看这两篇文章,帮助理解 非对称加密数字签名,写得挺好的。

  • RSA算法原理(一)
  • RSA算法原理(二)
  • 数字签名是什么?

非对称加密

在线加密测试工具

在线加密解密工具

参考相关文章

  • Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC
  • Java加密技术(二)——对称加密算法DES&AES
  • 【JAVA】AES加密 简单实现 AES-128/ECB/PKCS5Padding
  • java加解密之DES多种使用方式
  • 3DES加密算法
  • Java加密技术(四)——非对称加密算法RSA
  • RSA加密解密及数字签名Java实现
  • AES apache commons-crypto 对称加密

你可能感兴趣的:(加密,Java,算法)