任务详情
- 在openEuler(推荐)或Ubuntu或Windows(不推荐)中完成下面任务
- 参考附件内容完成 SM2 加解密的内容,提交运行结果截图(10‘)
- 完成 SM3,SM4 算法的调用,提交运行结果截图和代码(15’, 选做)
BouncyCastle配置
1.jar包下载
- 官网:https://www.bouncycastle.org/latest_releases.html
- bcprov-ext-jdk15to18-1.73.jar
- bcprov-jdk15to18-1.73.jar
2.将下载的两个jar包拷贝到 %JAVA_HOME%\jre\lib\ext 目录下面
3.修改配置文件 %JAVA_HOME%\jre\lib\security\java.security ,在末尾添加security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider ;
4.在项目中导入jar包: bcprov‐ext‐jdk15to18‐168.jar
代码
demo.java
import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.*; import java.security.spec.ECGenParameterSpec; import java.util.Arrays; public class demo { private static String M = "mrc20201330"; public static void main(String[] args) throws Exception { SM2Util sm2 = new SM2Util(); final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1"); // 获取一个椭圆曲线类型的密钥对生成器 final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider()); // 使用SM2参数初始化生成器 kpg.initialize(sm2Spec); // 获取密钥对 KeyPair keyPair = kpg.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); System.out.println("数据:" + M); String data = sm2.encrypt(publicKey, M); System.out.println("公钥加密:" + data); String text = sm2.decrypt(privateKey, data); System.out.println("私钥解密:" + text); SM3Util sm3 = new SM3Util(); byte[] digest = sm3.digest(M); System.out.println("SM3摘要:" + Arrays.toString(digest)); SM4Util sm4 = new SM4Util(); byte[] key1 = SM4Key.generateKey(); byte[] iv = null; byte[] sm4data = sm4.encrypt(digest, key1, SM4ModeAndPaddingEnum.SM4_ECB_NoPadding, iv); System.out.println("SM4加密:" + Arrays.toString(sm4data)); byte[] sm4text = sm4.decrypt(sm4data, key1, SM4ModeAndPaddingEnum.SM4_ECB_NoPadding, iv); System.out.println("SM4解密:" + Arrays.toString(sm4text)); } }
SM2Util.java
import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.params.*; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.util.encoders.Hex; import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; public class SM2Util { /** * SM2加密算法 * * @param publicKey 公钥 * @param data 明文数据 * @return **/ public String encrypt(PublicKey publicKey, String data) { ECPublicKeyParameters ecPublicKeyParameters = null; if (publicKey instanceof BCECPublicKey) { BCECPublicKey bcecPublicKey = (BCECPublicKey) publicKey; ECParameterSpec ecParameterSpec = bcecPublicKey.getParameters(); ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(), ecParameterSpec.getG(), ecParameterSpec.getN()); ecPublicKeyParameters = new ECPublicKeyParameters(bcecPublicKey.getQ(), ecDomainParameters); } SM2Engine sm2Engine = new SM2Engine(); sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom())); byte[] arrayOfBytes = null; try { byte[] in = data.getBytes(StandardCharsets.UTF_8); arrayOfBytes = sm2Engine.processBlock(in, 0, in.length); } catch (Exception e) { System.out.println("SM2加密时出现异常:"); } return Hex.toHexString(arrayOfBytes); } /** * SM2解密算法 * * @param privateKey 私钥 * @param cipherData 密文数据 * @return **/ public String decrypt(PrivateKey privateKey, String cipherData) { byte[] cipherDataByte = Hex.decode(cipherData); BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) privateKey; ECParameterSpec ecParameterSpec = bcecPrivateKey.getParameters(); ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(), ecParameterSpec.getG(), ecParameterSpec.getN()); ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(bcecPrivateKey.getD(), ecDomainParameters); SM2Engine sm2Engine = new SM2Engine(); sm2Engine.init(false, ecPrivateKeyParameters); String result = null; try { byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length); return new String(arrayOfBytes, StandardCharsets.UTF_8); } catch (Exception e) { System.out.println("SM2解密时出现异常"); } return result; } }
SM3Util.java
import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.Security; /** * @Description: 国密SM3摘要算法帮助类 * @Author: wucheng * @CreateDate: 2020/2/16 16:36 */ public class SM3Util { static { Security.addProvider(new BouncyCastleProvider()); } public byte[] digest(String input) { SM3Digest sm3Digest = new SM3Digest(); int length = input.length(); byte[] data = input.getBytes(); sm3Digest.update(data, 0, length); byte[] ret = new byte[sm3Digest.getDigestSize()]; sm3Digest.doFinal(ret, 0); return ret; } } SM4Key.java import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.KeyGenerator; import java.security.SecureRandom; import java.security.Security; /** * @Description: * @Author: wucheng * @CreateDate: 2020/2/16 16:51 */ public class SM4Key { static { Security.addProvider(new BouncyCastleProvider()); } public static byte[] generateKey() throws Exception { KeyGenerator kg = KeyGenerator.getInstance("SM4", BouncyCastleProvider.PROVIDER_NAME); kg.init(128, new SecureRandom()); return kg.generateKey().getEncoded(); } }
SM4Util.java
import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.Security; /** * @Description: 国密SM4对称加解密算法帮助类 * @Author: wucheng * @CreateDate: 2020/2/16 16:38 */ public class SM4Util { static { Security.addProvider(new BouncyCastleProvider()); } /** * SM4 加密 * * @param input 明文数据 * @param key 密钥 * @param sm4ModeAndPaddingEnum 加密模式和padding模式 * @param iv 初始向量(ECB模式下传NULL) * @return * @throws Exception */ public byte[] encrypt(byte[] input, byte[] key, SM4ModeAndPaddingEnum sm4ModeAndPaddingEnum, byte[] iv) throws Exception { return sm4(input, key, sm4ModeAndPaddingEnum, iv, Cipher.ENCRYPT_MODE); } /** * SM4 解密 * * @param input 密文数据 * @param key 密钥 * @param sm4ModeAndPaddingEnum 加密模式和padding模式 * @param iv 初始向量(ECB模式下传NULL) * @return * @throws Exception */ public byte[] decrypt(byte[] input, byte[] key, SM4ModeAndPaddingEnum sm4ModeAndPaddingEnum, byte[] iv) throws Exception { return sm4(input, key, sm4ModeAndPaddingEnum, iv, Cipher.DECRYPT_MODE); } private static byte[] sm4(byte[] input, byte[] key, SM4ModeAndPaddingEnum sm4ModeAndPaddingEnum, byte[] iv, int mode) throws Exception { IvParameterSpec ivParameterSpec = null; if (iv != null) { ivParameterSpec = new IvParameterSpec(iv); } SecretKeySpec sm4Key = new SecretKeySpec(key, "SM4"); Cipher cipher = Cipher.getInstance(sm4ModeAndPaddingEnum.getName(), BouncyCastleProvider.PROVIDER_NAME); if (ivParameterSpec == null) { cipher.init(mode, sm4Key); } else { cipher.init(mode, sm4Key, ivParameterSpec); } return cipher.doFinal(input); } }
SM4ModeAndPaddingEnum.java
/** * @Description: SM4对称加解密算法中的模式和padding方式枚举类 * @Author: wucheng * @CreateDate: 2020/2/16 16:39 */ public enum SM4ModeAndPaddingEnum { SM4_ECB_NoPadding("SM4/ECB/NoPadding"), SM4_ECB_PKCS5Padding("SM4/ECB/PKCS5Padding"), SM4_ECB_PKCS7Padding("SM4/ECB/PKCS7Padding"), SM4_CBC_NoPadding("SM4/CBC/NoPadding"), SM4_CBC_PKCS5Padding("SM4/CBC/PKCS5Padding"), SM4_CBC_PKCS7Padding("SM4/CBC/PKCS7Padding"); private String name; SM4ModeAndPaddingEnum(String name) { this.name = name; } public String getName() { return name; } }
实现
数据:mrc20201330 公钥加密:04bf3ae935ec9a3833e81968585b208297b62cc146cafed42089f625966b6a611484388b6c2d534d9e8ebe183ffd497b952308594a48c0595902cceff5dc538741876ac11057407ccac4f9170c5d531ae163547d05568cf67148e66fbd01ecf9f07105102cc09f7aecc2e44a 私钥解密:mrc20201330 SM3摘要:[-36, 113, -115, 111, -36, 52, 53, -24, 56, 85, -49, -120, -122, 120, 6, -74, -19, -8, -87, 63, 107, -58, -118, -32, -3, 26, -28, 56, 125, 96, 81, 54] SM4加密:[20, -57, -106, 102, 94, -82, 116, 93, -93, -34, -82, -101, -87, 26, 47, 95, 89, -40, -115, 115, 73, 124, 62, 113, -3, 117, 54, -6, -90, -19, -53, -65] SM4解密:[-36, 113, -115, 111, -36, 52, 53, -24, 56, 85, -49, -120, -122, 120, 6, -74, -19, -8, -87, 63, 107, -58, -118, -32, -3, 26, -28, 56, 125, 96, 81, 54]
标签:java,String,SM4,new,BouncyCastle,import,byte From: https://www.cnblogs.com/MRC-/p/17473011.html