zoukankan      html  css  js  c++  java
  • sm4加密

    前言

    项目里需要用到sm4加密,在这里记录一下(springboot)。

    依赖

    bouncycastle

    <!-- 一个开源的加解密算法包 -->
    <dependency>
    	<groupId>org.bouncycastle</groupId>
    	<artifactId>bcmail-jdk15on</artifactId>
    	<version>1.66</version>
    </dependency>
    <!-- 实用工具相关,这里主要用了里面的hexUtil,也可以自己封装 -->
    <dependency>
    	<groupId>cn.hutool</groupId>
    	<artifactId>hutool-all</artifactId>
    	<version>5.4.1</version>
    </dependency>
    

    代码

    直接贴代码,可以根据自己的需要封装相对应的代码逻辑。

    //需要注意的是,使用KeyGenerator生成密钥种子的时候,windows和linux上会产生不一致。
    //例如:
    KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, PROVIDER_NAME);
    SecureRandom random = new SecureRandom();
    if(null != seed && !"".equals(seed)){
    	random.setSeed(seed.getBytes());
    }
    kg.init(keySize, random);
    
    //解决办法
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    
    
    import cn.hutool.core.util.HexUtil;
    import com.spinfo.common.constants.UserConstants;
    import com.spinfo.controller.UserController;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.util.encoders.Base64;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.DigestUtils;
    
    import javax.crypto.*;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.*;
    import java.util.Arrays;
    
    public class SM4Util {
    
       private static Logger logger = LoggerFactory.getLogger(SM4Util.class);
    
       private static final String PROVIDER_NAME = "BC";
       public static final String ALGORITHM_NAME = "SM4";
       public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
       public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";
       public static final String DEFAULT_KEY = "random_seed";
       public static final int DEFAULT_KEY_SIZE = 128;
       private static final int ENCRYPT_MODE = 1;
       private static final int DECRYPT_MODE = 2;
    
       static {
          Security.addProvider(new BouncyCastleProvider());
       }
    
       public static byte[] generateKey() throws NoSuchAlgorithmException, NoSuchProviderException {
          return generateKey(DEFAULT_KEY, DEFAULT_KEY_SIZE);
       }
    
       public static byte[] generateKey(String seed) throws NoSuchAlgorithmException, NoSuchProviderException {
          return generateKey(seed, DEFAULT_KEY_SIZE);
       }
    
       public static byte[] generateKey(String seed, int keySize) throws NoSuchAlgorithmException, NoSuchProviderException {
          KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, PROVIDER_NAME);
          SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
          if(null != seed && !"".equals(seed)){
             random.setSeed(seed.getBytes());
          }
          kg.init(keySize, random);
          return kg.generateKey().getEncoded();
       }
    
       /**
        * ecb 加密
        * @param key
        * @param data
        */
       public static byte[] encryptEcbPadding(byte[] key, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
          Cipher cipher = generateEcbCipher(ENCRYPT_MODE, key);
          return cipher.doFinal(data);
       }
    
       /**
        * ecb 解密
        * @param key
        * @param cipherText
        */
       public static byte[] decryptEcbPadding(byte[] key, byte[] cipherText) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
          Cipher cipher = generateEcbCipher(DECRYPT_MODE, key);
          return cipher.doFinal(cipherText);
       }
    
       /**
        * cbc 加密
        * @param key
        * @param data
        */
       public static byte[] encryptCbcPadding(byte[] key, byte[] iv, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
          Cipher cipher = generateCbcCipher(ENCRYPT_MODE, key, iv);
          return cipher.doFinal(data);
       }
    
       public static String encryptCbcPaddingString(byte[] key, byte[] iv, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
          Cipher cipher = generateCbcCipher(ENCRYPT_MODE, key, iv);
          byte[] result = cipher.doFinal(data);
          return Base64.toBase64String(result);
       }
    
       /**
        * cbc 解密
        * @param key
        * @param iv
        * @param cipherText
        */
       public static byte[] decryptCbcPadding(byte[] key, byte[] iv, String cipherText) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException {
          byte[] cipherBytes = Base64.decode(cipherText);
          Cipher cipher = generateCbcCipher(DECRYPT_MODE, key, iv);
          return cipher.doFinal(cipherBytes);
       }
    
       public static byte[] decryptCbcPadding(byte[] key, byte[] iv, byte[] cipherText) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException {
          Cipher cipher = generateCbcCipher(DECRYPT_MODE, key, iv);
          return cipher.doFinal(cipherText);
       }
    
       /**
        * ecb cipher
        * @param mode
        * @param key
        * @return
        */
       private static Cipher generateEcbCipher(int mode, byte[] key) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException {
          Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, PROVIDER_NAME);
          Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
          cipher.init(mode, sm4Key);
          return cipher;
       }
    
       /**
        * cbc cipher
        * @param mode
        * @param key
        * @return
        */
       private static Cipher generateCbcCipher(int mode, byte[] key, byte[] iv) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
          Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING, PROVIDER_NAME);
          Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
          IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
          cipher.init(mode, sm4Key, ivParameterSpec);
          return cipher;
       }
    
       /**
        * ecb 加密 times 次
        * @param data
        * @param salt
        * @param times
        * @return=
        */
       public static String encryptEcbDataTimes(String data, String salt, int times) throws GeneralSecurityException {
          try {
             byte[] key = HexUtil.decodeHex(salt);
             byte[] bytes = data.getBytes();
    
             for(int i = 0; i < times; ++i) {
                bytes = encryptEcbPadding(key, bytes);
             }
    
             data = Base64.toBase64String(bytes);
             return data;
          } catch (BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException | NoSuchProviderException | NoSuchAlgorithmException | InvalidKeyException var5) {
             throw new GeneralSecurityException("SM4加密失败");
          }
       }
    
       /**
        * ecb 解密 times 次
        * @param data
        * @param salt
        * @param times
        * @return
        * @throws GeneralSecurityException
        */
       public static String decryptEcbDataTimes(String data, String salt, int times) throws GeneralSecurityException {
          try {
             byte[] bytes = Base64.decode(data);
             byte[] key = HexUtil.decodeHex(salt);
    
             for(int i = 0; i < times; ++i) {
                bytes = decryptEcbPadding(key, bytes);
             }
    
             data = new String(bytes);
             return data;
          } catch (BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException | NoSuchProviderException | NoSuchAlgorithmException | InvalidKeyException var5) {
             throw new GeneralSecurityException("SM4解密失败");
          }
       }
    
       /**
        * cbc 加密 times 次
        * @param data
        * @param salt
        * @param times
        * @return=
        */
       public static String encryptCbcDataTimes(String data, String salt, int times)  {
          try {
             byte[] iv = generateKey();
             byte[] key = generateKey(salt);
             byte[] bytes = data.getBytes();
    
             Cipher cipher = generateCbcCipher(ENCRYPT_MODE, key, iv);
             for(int i = 0; i < times; ++i) {
                bytes = cipher.doFinal(bytes);
             }
    
             data = Base64.toBase64String(bytes);
             return data;
          } catch (Exception e) {
             e.printStackTrace();
             return null;
          }
       }
    
       /**
        * cbc 解密 times 次
        * @param data
        * @param salt
        * @param times
        * @return
        * @throws GeneralSecurityException
        */
       public static String decryptCbcDataTimes(String data, String salt, int times) throws GeneralSecurityException {
          try {
             byte[] iv = generateKey();
             byte[] bytes = Base64.decode(data);
             byte[] key = generateKey(salt);
    
             Cipher cipher = generateCbcCipher(ENCRYPT_MODE, key, iv);
             for(int i = 0; i < times; ++i) {
                bytes = cipher.doFinal(bytes);
             }
    
             data = new String(bytes);
             return data;
          } catch (BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException | NoSuchProviderException | NoSuchAlgorithmException | InvalidKeyException var5) {
             throw new GeneralSecurityException("SM4解密失败");
          }
       }
    }
    
  • 相关阅读:
    了解Web2.0必订阅之十大Blog[个人推荐]
    [J2ME Q&A]Target port denied to untrusted applications问题回应
    2005年Csdn十大最热门BLog作者排名第一?
    J2me流媒体技术实现讨论[1]
    液氮
    微分、差分和变分的概念
    Python mutable vs immutable (不可变对象 vs 可变对象)
    异戊烷
    免疫组化
    [导入]java escape unescape
  • 原文地址:https://www.cnblogs.com/wmg92/p/13667567.html
Copyright © 2011-2022 走看看