系列文章目录
目录
前言
本篇主要介绍SM4算法在Java(JDK1.8)中如何实现,借助Java标准库或第三方库,非原始实现,较为基础。
一、SM4是什么?
SM4.0(原名SMS4.0)是中华人民共和国政府采用的一种分组密码标准,由国家密码管理局于2012年3月21日发布。相关标准为“GM/T 0002-2012《SM4分组密码算法》(原SMS4分组密码算法)”。 在商用密码体系中,SM4主要用于数据加密,其算法公开,分组长度与密钥长度均为128bit,加密算法与密钥扩展算法都采用32轮非线性迭代结构,S盒为固定的8比特输入8比特输出。
—— 百度百科
二、使用步骤
1、引入依赖
代码如下(示例):
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.78.1</version>
</dependency>
2、加密
代码如下(示例):
public class EncryptUtils {
static {
// 添加安全提供者(SM2,SM3,SM4等加密算法,CBC、CFB等加密模式,PKCS7Padding等填充方式,不在Java标准库中,由BouncyCastleProvider实现)
Security.addProvider(new BouncyCastleProvider());
}
/**
* SM4,商业密码(Shang Mi4)是中华人民共和国政府采用的一种分组密码标准,由国家密码管理局于2012年3月21日发布,相关标准为“GM/T 0002-2012《SM4分组密码算法》”。
* <p>
* 输入:待加密的字符串,16或24或32位字符串密码
* 输出:16进制字符串或Base64编码的字符串密文(常用)
* 应用:密码管理、数字签名、文件完整性校验
* 安全性:★★★★☆
*
* @param plainString 明文
* @param key 秘钥
* @return cipherString 密文
*/
public static String sm4Encrypt(String plainString, String key) {
String cipherString = null;
try {
// 指定加密算法
String algorithm = "SM4";
// 创建密钥规范
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);
// 获取Cipher对象实例(BC中SM4默认使用ECB模式和PKCS5Padding填充方式,因此下列模式和填充方式无需指定)
Cipher cipher = Cipher.getInstance(algorithm + "/ECB/PKCS5Padding");
// 初始化Cipher为加密模式
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
// 获取加密byte数组
byte[] cipherBytes = cipher.doFinal(plainString.getBytes(StandardCharsets.UTF_8));
// 输出为Base64编码
cipherString = Base64.getEncoder().encodeToString(cipherBytes);
} catch (Exception e) {
e.printStackTrace();
}
return cipherString;
}
}
3、解密
代码如下(示例):
public class EncryptUtils {
static {
// 添加安全提供者(SM2,SM3,SM4等加密算法,CBC、CFB等加密模式,PKCS7Padding等填充方式,不在Java标准库中,由BouncyCastleProvider实现)
Security.addProvider(new BouncyCastleProvider());
}
/**
* SM4,商业密码(Shang Mi4)是中华人民共和国政府采用的一种分组密码标准,由国家密码管理局于2012年3月21日发布,相关标准为“GM/T 0002-2012《SM4分组密码算法》”。
* <p>
* 输入:密文,16或24或32位字符串密码
* 输出:明文
* 应用:密码管理、数字签名、文件完整性校验
* 安全性:★★★★☆
*
* @param cipherString 密文
* @param key 秘钥
* @return plainString 明文
*/
public static String sm4Decrypt(String cipherString, String key) {
String plainString = null;
try {
// 指定加密算法
String algorithm = "SM4";
// 创建密钥规范
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);
// 获取Cipher对象实例(BC中SM4默认使用ECB模式和PKCS5Padding填充方式,因此下列模式和填充方式无需指定)
Cipher cipher = Cipher.getInstance(algorithm + "/ECB/PKCS5Padding");
// 初始化Cipher为解密模式
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
// 获取加密byte数组
byte[] cipherBytes = cipher.doFinal(Base64.getDecoder().decode(cipherString));
// 输出为字符串
plainString = new String(cipherBytes);
} catch (Exception e) {
e.printStackTrace();
}
return plainString;
}
}
三、测试
代码如下(示例):
public class EncryptUtils {
...
public static void main(String[] args) {
String plainString = "hello world, hello java!";
String sm4Encrypt = sm4Encrypt(plainString, "1234567812345678");
String sm4Decrypt = sm4Decrypt(sm4Encrypt, "1234567812345678");
System.out.println("--------------------------- sm4");
System.out.println("加密前: " + plainString);
System.out.println("加密后: " + sm4Encrypt);
System.out.println("解密后: " + sm4Decrypt);
}
}
运行截图
某网站运行截图
总结
以上就是今天要讲的内容,本文仅仅简单介绍了SM4加密算法在Java中的实现方式,各个加密算法的对比及总结请见本文系列文章汇总篇,水平有限,难免出错,仅供参考,不喜勿喷,感谢!更多内容请百度和ChatGPT!