BouncyCastle


BouncyCastle

實踐目標

  1. 在openEuler(推薦)或Ubuntu或Windows(不推薦)中完成下面任務
  2. 參考附件內容完成SM2加解密的內容,提交運行結果截圖(10‘)
  3. 完成SM3,SM4算法的調用,提交運行結果截圖和代碼(15’, 選做)

實踐實現

demo

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="zym55mmyz";

    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();
        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(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(Arrays.toString(sm4data));
        byte[] sm4text = sm4.decrypt(sm4data, key1,SM4ModeAndPaddingEnum.SM4_ECB_NoPadding,iv);
        System.out.println(Arrays.toString(sm4text));
    }
}

sm2

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;
    }
}

sm3

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;
    }
}

sm4-key

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();
    }
}

sm4-mode&PaddingEnum

/**
 * @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;
    }
}

sm4-util

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);
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM