赞
踩
国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位
一、SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
二、SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
三、SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
四、SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
POM依赖:
<!--国密-->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.56</version>
</dependency>
SM2加解密代码:
/** * @author SongWei * @version 1.0.0 * @ClassName spring-cloud.com.boot.cloud.encryption.sm.Sm2Utils.java * @Description SM2加解密工具类 * @createTime 2018年10月28日 13:57:00 */ public class Sm2Utils{ /** * 生成随机秘钥对 * * @Version: 1.0.0 * @return: Map<String, String> * @author: SongWei * @date: 2018/10/28 13:57 */ public static Map<String, String> generateKeyPair() { SM2 sm2 = SM2.Instance(); AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair(); ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate(); ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic(); //解密密钥 BigInteger privateKey = ecpriv.getD(); //加密密钥 ECPoint publicKey = ecpub.getQ(); Map<String, String> resutlMap = new HashMap<String, String>(); resutlMap.put("privateKey", SecurityUtils.byteToHex(privateKey.toByteArray())); resutlMap.put("publicKey", SecurityUtils.byteToHex(publicKey.getEncoded())); return resutlMap; } /** * SM2加密 * * @param publicKey <p>公钥</p> * @param data <p>需要加密的数据</p> * @Version: 1.0.0 * @return: String * @author: SongWei * @date: 2018/10/28 13:57 */ public static String encrypt(byte[] publicKey, byte[] data) throws IOException { if (publicKey == null || publicKey.length == 0) { return null; } if (data == null || data.length == 0) { return null; } byte[] source = new byte[data.length]; System.arraycopy(data, 0, source, 0, data.length); Cipher cipher = new Cipher(); SM2 sm2 = SM2.Instance(); ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey); ECPoint c1 = cipher.Init_enc(sm2, userKey); cipher.Encrypt(source); byte[] c3 = new byte[32]; cipher.Dofinal(c3); //C1 C2 C3拼装成加密字串 return SecurityUtils.byteToHex(c1.getEncoded()) + SecurityUtils.byteToHex(source) + SecurityUtils.byteToHex(c3); } /** * 数据解密 * * @param privateKey <p>私钥</p> * @param encryptedData <p>需要解密的内容</p> * @Version: 1.0.0 * @return: byte * @author: SongWei * @date: 2018/10/18 13:59 */ public static byte[] decrypt(byte[] privateKey, byte[] encryptedData) throws IOException { if (privateKey == null || privateKey.length == 0) { return null; } if (encryptedData == null || encryptedData.length == 0) { return null; } //加密字节数组转换为十六进制的字符串 长度变为encryptedData.length * 2 String data = SecurityUtils.byteToHex(encryptedData); /** * 分解加密字串 * (C1 = C1标志位2位 + C1实体部分128位 = 130) * (C3 = C3实体部分64位 = 64) * (C2 = encryptedData.length * 2 - C1长度 - C2长度) */ byte[] c1Bytes = SecurityUtils.hexToByte(data.substring(0, 130)); int c2Len = encryptedData.length - 97; byte[] c2 = SecurityUtils.hexToByte(data.substring(130, 130 + 2 * c2Len)); byte[] c3 = SecurityUtils.hexToByte(data.substring(130 + 2 * c2Len, 194 + 2 * c2Len)); SM2 sm2 = SM2.Instance(); BigInteger userD = new BigInteger(1, privateKey); //通过C1实体字节来生成ECPoint ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes); Cipher cipher = new Cipher(); cipher.Init_dec(userD, c1); cipher.Decrypt(c2); cipher.Dofinal(c3); //返回解密结果 return c2; } public static void main(String[] args) throws Exception { for (int i = 0; i < 200; i++) { //生成密钥对 Map<String, String> keyMap = generateKeyPair(); String plainText = "{"id":"123","name":"张三"}"; 加密密钥 String publicKey = keyMap.get("publicKey"); //解密蜜月 String privateKey = keyMap.get("privateKey"); String encString = SM2Utils.encrypt(SecurityUtils.hexStringToBytes(publicKey), plainText.getBytes()); System.out.println("密文:" + encString); byte[] plainString = SM2Utils.decrypt(SecurityUtils.hexStringToBytes(privateKey), SecurityUtils.hexStringToBytes(encString)); System.out.println(new String(plainString)); } } }
/** * @author SongWei * @version 1.0.0 * @ClassName spring-cloud.com.boot.cloud.sm.Sm2Tool.java * @Description TODO * @createTime 2018年10月28日 14:29:00 */ public class Sm2Tool { /** * 正式参数 * * @Version: 1.0.0 * @date: 2018年10月28日 14:29:00 */ public static String[] ecc_param = { "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" }; public static Sm2Tool Instance() { return new Sm2Tool(); } public final BigInteger ecc_p; public final BigInteger ecc_a; public final BigInteger ecc_b; public final BigInteger ecc_n; public final BigInteger ecc_gx; public final BigInteger ecc_gy; public final ECCurve ecc_curve; public final ECPoint ecc_point_g; public final ECDomainParameters ecc_bc_spec; public final ECKeyPairGenerator ecc_key_pair_generator; public final ECFieldElement ecc_gx_fieldsmen; public final ECFieldElement ecc_gy_fieldsmen; public Sm2Tool() { this.ecc_p = new BigInteger(ecc_param[0], 16); this.ecc_a = new BigInteger(ecc_param[1], 16); this.ecc_b = new BigInteger(ecc_param[2], 16); this.ecc_n = new BigInteger(ecc_param[3], 16); this.ecc_gx = new BigInteger(ecc_param[4], 16); this.ecc_gy = new BigInteger(ecc_param[5], 16); this.ecc_gx_fieldsmen = new Fp(this.ecc_p, this.ecc_gx); this.ecc_gy_fieldsmen = new Fp(this.ecc_p, this.ecc_gy); this.ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b); this.ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldsmen, this.ecc_gy_fieldsmen); this.ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n); ECKeyGenerationParameters ecc_engender; ecc_engender = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom()); this.ecc_key_pair_generator = new ECKeyPairGenerator(); this.ecc_key_pair_generator.init(ecc_engender); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。