作业1
SM2加解密内容:
package chenchen; 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.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("UTF8"); 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, "UTF8"); } catch (Exception e) { System.out.println("SM2解密时出现异常"); } return result; } }
package chenchen; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.*; import java.security.spec.ECGenParameterSpec; public class sm2_demo { private static String M="20181217cindy_SM2_demo"; public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { 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("明文: "+ M); System.out.println("密文:"+ data); String text=sm2.decrypt(privateKey,data); System.out.println("解密结果:"+ text); } }
sm3哈希算法:
package chenchen;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.*;
import java.util.Arrays;
import javax.xml.bind.DatatypeConverter;
public class SM3Util {
public static void main(String[] args) throws NoSuchAlgorithmException {
BouncyCastleProvider provider = new BouncyCastleProvider();
byte[] word = "20181217cindy".getBytes();
MessageDigest digest = MessageDigest.getInstance("SM3", provider);
byte[] word1 = digest.digest(word);
String word2 = DatatypeConverter.printHexBinary(word1);
System.out.printf("sm3: %s\n", word2);
}
}
package chenchen; import java.security.AlgorithmParameters; import java.security.Key; import java.security.Security; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class SM4Util{ //算法名 public static final String KEY_ALGORITHM = "SM4"; //加解密算法/模式/填充方式 //可以任意选择,为了方便后面与iOS端的加密解密,采用与其相同的模式与填充方式 //ECB模式只用密钥即可对数据进行加密解密,CBC模式需要添加一个参数iv public static final String CIPHER_ALGORITHM = "SM4/CBC/PKCS7Padding"; //生成密钥 public static byte[] generateKey() throws Exception{ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM); keyGenerator.init(128); SecretKey key = keyGenerator.generateKey(); return key.getEncoded(); } //生成iv public static AlgorithmParameters generateIV() throws Exception{ //iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0 byte[] iv = new byte[16]; Arrays.fill(iv, (byte) 0x00); AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_ALGORITHM); params.init(new IvParameterSpec(iv)); return params; } //转化成JAVA的密钥格式 public static Key convertToKey(byte[] keyBytes) throws Exception{ SecretKey secretKey = new SecretKeySpec(keyBytes,KEY_ALGORITHM); return secretKey; } //加密 public static byte[] encrypt(byte[] data,byte[] keyBytes,AlgorithmParameters iv) throws Exception { //转化为密钥 Key key = convertToKey(keyBytes); Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); //设置为加密模式 cipher.init(Cipher.ENCRYPT_MODE, key,iv); return cipher.doFinal(data); } //解密 public static byte[] decrypt(byte[] encryptedData,byte[] keyBytes,AlgorithmParameters iv) throws Exception{ Key key = convertToKey(keyBytes); Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); //设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, key,iv); return cipher.doFinal(encryptedData); } public static void main(String[] args) { //明文 String plainTextString = "20181217"; System.out.println("明文 : "+plainTextString); byte[] key; try { //初始化密钥 key = generateKey(); //初始化iv AlgorithmParameters iv = generateIV(); System.out.println("密钥 : "); //打印密钥 for (int i = 0; i < key.length; i++) { System.out.printf("%x", key[i]); } System.out.println(); //进行加密 byte[] encryptedData = encrypt(plainTextString.getBytes(), key,iv); //输出加密后的数据 System.out.println("加密后的数据 : "); for (int i = 0; i < encryptedData.length; i++) { System.out.printf("%x", encryptedData[i]); } System.out.println(); //进行解密 byte[] data = decrypt(encryptedData, key,iv); System.out.println("解密得到的数据 : " + new String(data)); } catch (Exception e) { e.printStackTrace(); } } }