mirror of
https://gitee.com/willfree/min-dev-java.git
synced 2026-10-04 19:42:01 +08:00
121 lines
5.9 KiB
Java
121 lines
5.9 KiB
Java
package minsecurity.crypto;
|
|
|
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
|
|
import javax.crypto.*;
|
|
import javax.crypto.spec.IvParameterSpec;
|
|
import javax.crypto.spec.SecretKeySpec;
|
|
import java.security.*;
|
|
|
|
/*
|
|
* @Author: hongyu guo
|
|
* @Description: sm4算法
|
|
* @Version: 1.0.0
|
|
* @Date: 16:26 2021/03/04
|
|
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
|
*/
|
|
public class SM4 {
|
|
static {
|
|
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
|
}
|
|
public static final String ALGORITHM_NAME = "SM4";
|
|
public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
|
|
public static final String ALGORITHM_NAME_ECB_NOPADDING = "SM4/ECB/NoPadding";
|
|
public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";
|
|
public static final String ALGORITHM_NAME_CBC_NOPADDING = "SM4/CBC/NoPadding";
|
|
|
|
/**
|
|
* SM4算法目前只支持128位(即密钥16字节)
|
|
*/
|
|
public static final int DEFAULT_KEY_SIZE = 128;
|
|
|
|
public static byte[] generateKey() throws NoSuchAlgorithmException, NoSuchProviderException {
|
|
return generateKey(DEFAULT_KEY_SIZE);
|
|
}
|
|
|
|
public static byte[] generateKey(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException {
|
|
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
|
|
kg.init(keySize, new SecureRandom());
|
|
return kg.generateKey().getEncoded();
|
|
}
|
|
|
|
public static byte[] encrypt_ECB_Padding(byte[] key, byte[] data)
|
|
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
|
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
|
|
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
|
|
return cipher.doFinal(data);
|
|
}
|
|
|
|
public static byte[] decrypt_ECB_Padding(byte[] key, byte[] cipherText)
|
|
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
|
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
|
|
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
|
|
return cipher.doFinal(cipherText);
|
|
}
|
|
|
|
public static byte[] encrypt_ECB_NoPadding(byte[] key, byte[] data)
|
|
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
|
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
|
|
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.ENCRYPT_MODE, key);
|
|
return cipher.doFinal(data);
|
|
}
|
|
|
|
public static byte[] decrypt_ECB_NoPadding(byte[] key, byte[] cipherText)
|
|
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
|
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
|
|
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.DECRYPT_MODE, key);
|
|
return cipher.doFinal(cipherText);
|
|
}
|
|
|
|
public static byte[] encrypt_CBC_Padding(byte[] key, byte[] iv, byte[] data)
|
|
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
|
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
|
|
InvalidAlgorithmParameterException {
|
|
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.ENCRYPT_MODE, key, iv);
|
|
return cipher.doFinal(data);
|
|
}
|
|
|
|
public static byte[] decrypt_CBC_Padding(byte[] key, byte[] iv, byte[] cipherText)
|
|
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
|
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
|
|
InvalidAlgorithmParameterException {
|
|
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.DECRYPT_MODE, key, iv);
|
|
return cipher.doFinal(cipherText);
|
|
}
|
|
|
|
public static byte[] encrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] data)
|
|
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
|
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
|
|
InvalidAlgorithmParameterException {
|
|
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.ENCRYPT_MODE, key, iv);
|
|
return cipher.doFinal(data);
|
|
}
|
|
|
|
public static byte[] decrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] cipherText)
|
|
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
|
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
|
|
InvalidAlgorithmParameterException {
|
|
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.DECRYPT_MODE, key, iv);
|
|
return cipher.doFinal(cipherText);
|
|
}
|
|
|
|
private static Cipher generateECBCipher(String algorithmName, int mode, byte[] key)
|
|
throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
|
|
InvalidKeyException {
|
|
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
|
|
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
|
|
cipher.init(mode, sm4Key);
|
|
return cipher;
|
|
}
|
|
|
|
private static Cipher generateCBCCipher(String algorithmName, int mode, byte[] key, byte[] iv)
|
|
throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
|
|
NoSuchProviderException, NoSuchPaddingException {
|
|
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
|
|
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
|
|
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
|
|
cipher.init(mode, sm4Key, ivParameterSpec);
|
|
return cipher;
|
|
}
|
|
}
|