赞
踩
和 SM2 引入的包一样, SM2 为非对称算案发,SM4 为对称算法
【烦人的加密算法】国密SM2的使用–Java版本
SM4Utils 直接可用
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.Key;
import java.security.Security;
import java.util.Base64;
/**
* SM4加密算法
*
* @author hcf
* @date 2021/8/31 16:51
*/
@Slf4j
public class SM4Utils {
public static final String ALGORITHM_NAME = "SM4";
public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding";
public SM4Utils() {
}
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 加密
*
* @param hexKey 明文密钥
* @param content 内容
* @param charset 编码
* @return 加密数据
*/
public static String encrypt(String hexKey, String content, Charset charset) {
String encryptContent = StringUtils.EMPTY;
try {
byte[] keyData = ByteUtils.fromHexString(hexKey);
byte[] contentData = content.getBytes(charset);
byte[] encryptData = encryptEcbPadding(keyData, contentData);
encryptContent = Base64.getEncoder().encodeToString(encryptData);
} catch (Exception e) {
log.error("SM4Utils.encrypt(String hexKey, String content, String charset) error {}", e.getMessage(), e);
}
return encryptContent;
}
public static byte[] encryptEcbPadding(byte[] key, byte[] data) throws Exception {
Cipher cipher = generateEcbCipher(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
/**
* 解密
*
* @param hexKey 密钥
* @param encryptContent 密文
* @param charset 编码
* @return 解密数据
*/
public static String decrypt(String hexKey, String encryptContent, Charset charset) {
String content = StringUtils.EMPTY;
try {
byte[] keyData = ByteUtils.fromHexString(hexKey);
byte[] encryptData = Base64.getDecoder().decode(encryptContent);
byte[] contentData = decryptEcbPadding(keyData, encryptData);
content = new String(contentData, charset);
} catch (Exception e) {
log.error("SM4Utils.encrypt(String hexKey, String content, String charset) error {}", e.getMessage(), e);
}
return content;
}
private static byte[] decryptEcbPadding(byte[] key, byte[] cipherText) throws Exception {
Cipher cipher = generateEcbCipher(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
private static Cipher generateEcbCipher(int mode, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
cipher.init(mode, sm4Key);
return cipher;
}
public static void main(String[] args) throws Exception {
String hexCipher = CipherUtils.randomHexCipher();
String encrypt = encrypt(hexCipher, "content", StandardCharsets.UTF_8);
System.out.println(encrypt);
System.out.println(decrypt(hexCipher, encrypt, StandardCharsets.UTF_8));
}
}
CipherUtils
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.security.SecureRandom;
import java.util.Random;
/**
* 密钥生成工具类
*
* @author hcf
* @date 2021/9/1 17:44
*/
@Slf4j
public class CipherUtils {
private static final int AES_KEY_LENGTH = 16;
public static String randomHexCipher() {
String cipher = randomCipher();
StringBuilder hexCipher = new StringBuilder(StringUtils.EMPTY);
for (int i = 0; i < cipher.length(); i++) {
int ch = cipher.charAt(i);
String s4 = Integer.toHexString(ch);
hexCipher.append(s4);
}
return hexCipher.toString();
}
/**
* 生成密钥
*
* @return 密钥
*/
public static String randomCipher() {
char[] chars = new char[AES_KEY_LENGTH];
SecureRandom rnd = new SecureRandom();
chars[nextIndex(chars, rnd)] = nextUpperlLetter(rnd);
chars[nextIndex(chars, rnd)] = nextLowerLetter(rnd);
chars[nextIndex(chars, rnd)] = nextNumLetter(rnd);
for (int i = 0; i < chars.length; i++) {
if (chars[i] == 0) {
chars[i] = nextChar(rnd);
}
}
return new String(chars);
}
private static int nextIndex(char[] chars, SecureRandom rnd) {
int index = rnd.nextInt(chars.length);
while (chars[index] != 0) {
index = rnd.nextInt(chars.length);
}
return index;
}
private static char nextUpperlLetter(Random rnd) {
return (char) ('A' + rnd.nextInt(26));
}
private static char nextLowerLetter(Random rnd) {
return (char) ('a' + rnd.nextInt(26));
}
private static char nextNumLetter(Random rnd) {
return (char) ('0' + rnd.nextInt(10));
}
private static char nextChar(SecureRandom rnd) {
switch (rnd.nextInt(3)) {
case 0:
return (char) ('a' + rnd.nextInt(26));
case 1:
return (char) ('A' + rnd.nextInt(26));
default:
return (char) ('0' + rnd.nextInt(10));
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。