目前国密算法有多种, 网上有多种开源实现,这里选择用腾讯的包。
依赖如下:
<dependency>
<groupId>com.tencent.kona</groupId>
<artifactId>kona-crypto</artifactId>
<version>1.0.12</version>
</dependency>
<dependency>
<groupId>com.tencent.kona</groupId>
<artifactId>kona-provider</artifactId>
<version>1.0.12</version>
</dependency>
测试代码如下:
import com.tencent.kona.crypto.KonaCryptoProvider;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class Main {
public static void main(String[] args) throws Exception {
new Main().testSpeed();
}
public void test() throws Exception {
System.out.println("Hello world!");
Security.addProvider(new KonaCryptoProvider());
/**
*
SM4/CBC/NoPadding:使用CBC分组操作模式,不使用填充。明文或密文的长度必须是16字节的整数倍。
SM4/CBC/PKCS7Padding:使用CBC分组操作模式,且使用PKCS#7填充。明文或密文的长度可以不是16字节的整数倍。
SM4/CTR/NoPadding:使用CTR分组操作模式,不使用填充。明文或密文的长度可以不是16字节的整数倍。
SM4/ECB/NoPadding:使用ECB分组操作模式,不使用填充。明文或密文的长度必须是16字节的整数倍。
SM4/ECB/PKCS7Padding:使用ECB分组操作模式,且使用PKCS#7填充。明文或密文的长度可以不是16字节的整数倍。
SM4/GCM/NoPadding:使用GCM分组操作模式,不使用填充。明文或密文的长度可以不是16字节的整数倍。
*/
byte[] message = "zhujinshan朱金山&&##".getBytes(StandardCharsets.UTF_8);
byte[] key = "0123456789abcdeffedcba9876543210".getBytes(StandardCharsets.UTF_8);
SecretKey secretKey = new SecretKeySpec(key, "SM4");
Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] ciphertext = cipher.doFinal(message);
// 解密
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] cleartext = cipher.doFinal(ciphertext);
System.out.println(new String(cleartext, StandardCharsets.UTF_8));
}
public void testSpeed() throws Exception {
System.out.println("Hello world!");
Security.addProvider(new KonaCryptoProvider());
byte[] key = "goodjobsisright9".getBytes(StandardCharsets.UTF_8);
SecretKey secretKey = new SecretKeySpec(key, "SM4");
Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS7Padding");
int LIMIT = 1200;
// 批量生成明文
String[] list = new String[LIMIT];
for (int i = 0; i < LIMIT; i++) {
list[i] = UUID.randomUUID().toString();
}
List<byte[]> ciperList = new ArrayList(LIMIT);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
for(String s : list) {
ciperList.add(cipher.doFinal(s.getBytes(StandardCharsets.UTF_8)));
}
System.out.println("加密完成");
String[] afterAll = new String[LIMIT];
long t1 = System.currentTimeMillis();
cipher.init(Cipher.DECRYPT_MODE, secretKey);
int i = 0;
for (byte[] bs : ciperList) {
afterAll[i] = new String(cipher.doFinal(bs), StandardCharsets.UTF_8);
i++;
}
long t2 = System.currentTimeMillis();
System.out.println("耗时:" + (t2 - t1));
for (int j = 0; j < LIMIT; j++) {
if (!afterAll[j].equals(list[j])) {
System.out.println("------chucuole");
}
}
}
}
简单试了下,速度还可以