logo头像

From zero to HERO

Java中的加密算法和摘要算法

1. 前言

Java中使用密码算法、摘要算法是很常见的,而且自行实现也是门槛较高的,除了需要对对应算法的规则了如执掌之外还要使用诸如位运算、十六进制、八进制等来回转换。你以为这样就完了?还有Java自身提供的JCA( Java加密体系结构)**、JCE(Java加密扩展)JSSE(Java安全套接字扩展)**等等等等,能看得你怀疑人生。折腾半天,算了还是找个类库搞搞算了。今天就推荐一个专业的密码类库。

2. Bouncy Castle

Bouncy Castle是java的一个开源JCE提供者,提供了目前最全面的密码学算法。目前常用的版本有两个:

JDK1.5版本

阉割版

<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcprov-jdk15on</artifactId>
  <version>1.66</version>
</dependency>

完全版本artifactId=bcprov-ext-jdk15on

JDK1.5-JDK8版本

阉割版

<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcprov-jdk15to18</artifactId>
  <version>1.66</version>
</dependency>

完全版本artifactId=bcprov-ext-jdk15to18

3. 简单演示

Bouncy Castle 提供的一部分算法实现

上图看上去不少,其实只占了很少一部分。这里就简单演示两个经常使用的算法,一种摘要算法,一种加密算法。

MD5摘要算法。

/**
 * bouncyCastle md5摘要.
 *
 * @param src the src
 * @return the string
 */
public String bouncyCastleMD5(String src) {
    // 初始化MD5摘要
    Digest digest = new MD5Digest();
    // 需要摘要的字节
    byte[] bytes = src.getBytes(StandardCharsets.UTF_8);
    // 更新
    digest.update(bytes, 0, bytes.length);
    byte[] md5Bytes = new byte[digest.getDigestSize()];
    // 执行
    digest.doFinal(md5Bytes, 0);
    // 16进制运算
    return Hex.toHexString(md5Bytes).toUpperCase();
}

是不是很简洁?还有SHA256SHA512等等,你可以试一试。

AES加密算法

String src = "felord.cn";
// AES 密钥最低128 位  那么就是 16位字符串
String password = "ffffffffffffffff";
// 加载BC 提供的算法到 Java JCE
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// 获取AES 密码机实例
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
// 初始化加密机
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(password.getBytes(StandardCharsets.UTF_8), "AES"));
// 执行加密
byte[] bytes = cipher.doFinal(src.getBytes(StandardCharsets.UTF_8));
// 十六进制编码
String encrypt = Hex.toHexString(bytes).toUpperCase();
 // encrypt =  93B5444D7A2BFDA597411B23FFBB014D
System.out.println("encrypt = " + encrypt);

// 逆着退回去
// 初始化解密
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(password.getBytes(StandardCharsets.UTF_8), "AES"));
// 对加密过的进行16进制解码
byte[] decode = Hex.decode(encrypt.getBytes(StandardCharsets.UTF_8));
// 执行解密
byte[] decrypt = cipher.doFinal(decode);
// decrypt = felord.cn
System.out.println("decrypt = " + new String(decrypt));

这里演示了使用AES算法将felord.cn加密然后在解密。其它算法我提供了所有的演示DEMO,有兴趣研究的可以关注公众号:码农小胖哥 回复 bouncy 获取。

3. 使用风险

这一点是很容易被很多人忽略的,其实密码算法在各个国家,包括我国都是限制性的管制技术。相关软件在出口时会被审查合规性。甚至在有些国家密码算法是有专利的,涉及到相关进出口业务时可能需要考虑合规检查。

评论系统未开启,无法评论!