sm4算法 java_SM4国密算法java实现

本文介绍了如何在Java中使用BouncyCastle库实现SM4加密算法,包括密钥生成、加密、解密和校验过程。示例代码详细展示了ECB模式下SM4的加解密操作。
摘要由CSDN通过智能技术生成

importorg.apache.commons.codec.binary.Hex;importorg.bouncycastle.jce.provider.BouncyCastleProvider;importorg.bouncycastle.pqc.math.linearalgebra.ByteUtils;importjavax.crypto.Cipher;importjavax.crypto.KeyGenerator;importjavax.crypto.spec.SecretKeySpec;importjava.security.Key;importjava.security.SecureRandom;importjava.security.Security;importjava.util.Arrays;public classSm4Util {static{

Security.addProvider(newBouncyCastleProvider());

}private static final String ENCODING = "UTF-8";public static final String ALGORITHM_NAME = "SM4";//加密算法/分组加密模式/分组填充方式//PKCS5Padding-以8个字节为一组进行分组加密//定义分组加密模式使用:PKCS5Padding

public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";//128-32位16进制;256-64位16进制

public static final int DEFAULT_KEY_SIZE = 128;/*** 自动生成密钥

*

*@return* @explain*/

public static String generateKey() throwsException {return new String(Hex.encodeHex(generateKey(DEFAULT_KEY_SIZE),false));

}/***@paramkeySize

*@return*@throwsException

* @explain*/

public static byte[] generateKey(int keySize) throwsException {

KeyGenerator kg=KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);

kg.init(keySize,newSecureRandom());returnkg.generateKey().getEncoded();

}/*** 生成ECB暗号

*

*@paramalgorithmName 算法名称

*@parammode 模式

*@paramkey

*@return*@throwsException

* @explain ECB模式(电子密码本模式:Electronic codebook)*/

private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throwsException {

Cipher cipher=Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);

Key sm4Key= newSecretKeySpec(key, ALGORITHM_NAME);

cipher.init(mode, sm4Key);returncipher;

}/*** sm4加密

*

*@paramhexKey 16进制密钥(忽略大小写)

*@paramparamStr 待加密字符串

*@return返回16进制的加密字符串

* @explain 加密模式:ECB

* 密文长度不固定,会随着被加密字符串长度的变化而变化*/

public staticString encryptEcb(String hexKey, String paramStr) {try{

String cipherText= "";//16进制字符串-->byte[]

byte[] keyData =ByteUtils.fromHexString(hexKey);//String-->byte[]

byte[] srcData =paramStr.getBytes(ENCODING);//加密后的数组

byte[] cipherArray =encrypt_Ecb_Padding(keyData, srcData);//byte[]-->hexString

cipherText =ByteUtils.toHexString(cipherArray);returncipherText;

}catch(Exception e) {returnparamStr;

}

}/*** 加密模式之Ecb

*

*@paramkey

*@paramdata

*@return*@throwsException

* @explain*/

public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throwsException {

Cipher cipher=generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);returncipher.doFinal(data);

}/*** sm4解密

*

*@paramhexKey 16进制密钥

*@paramcipherText 16进制的加密字符串(忽略大小写)

*@return解密后的字符串

*@throwsException

* @explain 解密模式:采用ECB*/

public staticString decryptEcb(String hexKey, String cipherText) {//用于接收解密后的字符串

String decryptStr = "";//hexString-->byte[]

byte[] keyData =ByteUtils.fromHexString(hexKey);//hexString-->byte[]

byte[] cipherData =ByteUtils.fromHexString(cipherText);//解密

byte[] srcData = new byte[0];try{

srcData=decrypt_Ecb_Padding(keyData, cipherData);//byte[]-->String

decryptStr = newString(srcData, ENCODING);

}catch(Exception e) {

e.printStackTrace();

}returndecryptStr;

}/*** 解密

*

*@paramkey

*@paramcipherText

*@return*@throwsException

* @explain*/

public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throwsException {

Cipher cipher=generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);returncipher.doFinal(cipherText);

}/*** 校验加密前后的字符串是否为同一数据

*

*@paramhexKey 16进制密钥(忽略大小写)

*@paramcipherText 16进制加密后的字符串

*@paramparamStr 加密前的字符串

*@return是否为同一数据

*@throwsException

* @explain*/

public static boolean verifyEcb(String hexKey, String cipherText, String paramStr) throwsException {//用于接收校验结果

boolean flag = false;//hexString-->byte[]

byte[] keyData =ByteUtils.fromHexString(hexKey);//将16进制字符串转换成数组

byte[] cipherData =ByteUtils.fromHexString(cipherText);//解密

byte[] decryptData =decrypt_Ecb_Padding(keyData, cipherData);//将原字符串转换成byte[]

byte[] srcData =paramStr.getBytes(ENCODING);//判断2个数组是否一致

flag =Arrays.equals(decryptData, srcData);returnflag;

}public static voidmain(String[] args) {try{

String json= "BF7B6BD7C1204BC4F3C87D235692DE9DBF7B6BD7C1204BC4F3C87D235692DE9DBF7B6BD7C1204BC4F3C87D235692DE9D";

System.out.println("加密前源数据————" +json);//生成32位16进制密钥

String key =Sm4Util.generateKey();

System.out.println(key+ "-----生成key");

String cipher=Sm4Util.encryptEcb(key, json);

System.out.println("加密串---" +cipher);

System.out.println(Sm4Util.verifyEcb(key, cipher, json));

json=Sm4Util.decryptEcb(key, cipher);

System.out.println("解密后数据---" +json);

}catch(Exception e) {

e.printStackTrace();

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值