当前位置: 首页 > news >正文

为什么建设银行网站打不开霸州放心的网络建站

为什么建设银行网站打不开,霸州放心的网络建站,dell网站的网站设计特色,自己做图片上传网站6.开源非对称加密算法SM2实现 前期内容导读: 开源加解密RSA/AES/SHA1/PGP/SM2/SM3/SM4介绍开源AES/SM4/3DES对称加密算法介绍及其实现开源AES/SM4/3DES对称加密算法的验证实现开源非对称加密算法RSA/SM2实现及其应用开源非对称加密算法RSA实现 1. 开源组件 非对称秘…

6.开源非对称加密算法SM2实现

前期内容导读:

  1. 开源加解密RSA/AES/SHA1/PGP/SM2/SM3/SM4介绍
  2. 开源AES/SM4/3DES对称加密算法介绍及其实现
  3. 开源AES/SM4/3DES对称加密算法的验证实现
  4. 开源非对称加密算法RSA/SM2实现及其应用
  5. 开源非对称加密算法RSA实现

1. 开源组件 非对称秘钥加密介绍

  • 加密组件引入方法:
    <dependency><groupId>com.biuqu</groupId><artifactId>bq-encryptor</artifactId><version>1.0.1</version>
    </dependency>
    

1.1 SM2的加解密实现

  • 加解密核心逻辑
    public byte[] doCipher(byte[] data, byte[] key, int cipherMode)
    {SM2Engine.Mode mode = SM2Engine.Mode.C1C2C3;if (!this.getPaddingMode().equalsIgnoreCase(String.valueOf(DEFAULT_MODE))){mode = SM2Engine.Mode.C1C3C2;}SM2Engine sm2Engine = new SM2Engine(mode);this.initSm2Engine(sm2Engine, key, cipherMode);try{return sm2Engine.processBlock(data, 0, data.length);}catch (Exception e){throw new EncryptionException("failed to do sm2 cipher.", e);}
    }private void initSm2Engine(SM2Engine sm2Engine, byte[] key, int cipherMode)
    {if (Cipher.ENCRYPT_MODE == cipherMode){ECPublicKey keyObj = (ECPublicKey)this.toPubKey(key);ECDomainParameters domainParam = this.getDomainParam(keyObj);ECKeyParameters keyParam = new ECPublicKeyParameters(keyObj.getQ(), domainParam);byte[] initKey = UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8);sm2Engine.init(true, new ParametersWithRandom(keyParam, this.createRandom(initKey)));}else{ECPrivateKey keyObj = (ECPrivateKey)this.toPriKey(key);ECDomainParameters domainParam = this.getDomainParam(keyObj);ECKeyParameters keyParam = new ECPrivateKeyParameters(keyObj.getD(), domainParam);sm2Engine.init(false, keyParam);}
    }  
    

    说明:

    1. 上面的代码阐述了加解密的核心流程:根据二进制生成秘钥,再基于单独的API计算得到加解密结果,该计算逻辑完全不同于以往的加解密API;
    2. 通过上述核心代码逻辑,再对比上篇5.非对称加密算法RSA实现,可知SM2本身是支持分段的;
    3. 通过秘钥二进制反向生成秘钥对象是一个有意思且有点复杂的事情,后面再单独说明;

1.2 SM2生成秘钥及转换实现

  • 秘钥生成逻辑

    public KeyPair createKey(byte[] initKey)
    {try{ECGenParameterSpec paramSpec = new ECGenParameterSpec(SM2_VERSION);KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM, this.getProvider());if (null == initKey){initKey = UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8);}SecureRandom random = this.createRandom(initKey);keyGen.initialize(paramSpec, random);return keyGen.generateKeyPair();}catch (Exception e){throw new EncryptionException("failed to get sm2 key.", e);}
    }
    
  • 公钥、私钥反向生成逻辑

    public PublicKey toPubKey(byte[] pubKey)
    {try{String hexKey = Hex.toHexString(pubKey);KeyFactory kf = KeyFactory.getInstance(ALGORITHM, this.getProvider());if (hexKey.startsWith(STANDARD_HEX_KEY_PREFIX)){return kf.generatePublic(new X509EncodedKeySpec(pubKey));}else{// 获取SM2相关参数X9ECParameters ecParam = GMNamedCurves.getByName(SM2_VERSION);// 将公钥HEX字符串转换为椭圆曲线对应的点ECCurve ecCurve = ecParam.getCurve();ECPoint ecPoint = ecCurve.decodePoint(pubKey);// 椭圆曲线参数规格ECParameterSpec ecSpec = new ECParameterSpec(ecCurve, ecParam.getG(), ecParam.getN(), ecParam.getH());// 将椭圆曲线点转为公钥KEY对象return kf.generatePublic(new ECPublicKeySpec(ecPoint, ecSpec));}}catch (Exception e){throw new EncryptionException("failed to get sm2 pub key.", e);}
    }public PrivateKey toPriKey(byte[] priKey)
    {try{String hexKey = Hex.toHexString(priKey);KeyFactory kf = KeyFactory.getInstance(ALGORITHM, this.getProvider());if (hexKey.startsWith(STANDARD_HEX_KEY_PREFIX)){PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(priKey);return kf.generatePrivate(keySpec);}else{// 获取SM2相关参数X9ECParameters ecParam = GMNamedCurves.getByName(SM2_VERSION);ECCurve ecCurve = ecParam.getCurve();// 椭圆曲线参数规格ECParameterSpec ecSpec = new ECParameterSpec(ecCurve, ecParam.getG(), ecParam.getN(), ecParam.getH());// 将私钥HEX字符串转换为16进制的数字值BigInteger bigInteger = new BigInteger(Hex.toHexString(priKey), EncryptionConst.HEX_UNIT);// 将X值转为私钥KEY对象return kf.generatePrivate(new ECPrivateKeySpec(bigInteger, ecSpec));}}catch (Exception e){throw new EncryptionException("failed to get sm2 pri key.", e);}
    }
    

    说明:SM2基于椭圆的原理来加解密,其秘钥生成和解析方式也与其它方式不同。

    1. SM2支持标准的秘钥生成方式:
    BaseSingleSignature sm2 = new Sm2Encryption();
    KeyPair keyPair = sm2.createKey(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
    byte[] priKey0 = keyPair.getPrivate().getEncoded();
    byte[] pubKey0 = keyPair.getPublic().getEncoded();
    
    1. SM2支持非标准的秘钥生成方式:
    BaseSingleSignature sm2 = new Sm2Encryption();
    KeyPair keyPair = sm2.createKey(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
    byte[] priKey1 = ((BCECPrivateKey)keyPair.getPrivate()).getD().toByteArray();
    byte[] pubKey1 = ((BCECPublicKey)keyPair.getPublic()).getQ().getEncoded(false);
    byte[] pubKey2 = ((BCECPublicKey)keyPair.getPublic()).getQ().getEncoded(true);
    
    1. 上述正文部分的秘钥转换逻辑可以无感兼容上述各种秘钥场景。有兴趣可以看看此算法的单元测试类。PS:网上资料通常只描述了其中一种秘钥生成场景,但是相互间是不兼容的。
  • 签名和验签判定逻辑:

    public byte[] sign(byte[] data, byte[] key)
    {try{PrivateKey priKey = this.toPriKey(key);Signature signature = Signature.getInstance(this.getSignatureAlg(), this.getProvider());signature.initSign(priKey);signature.update(data);return signature.sign();}catch (Exception e){throw new EncryptionException("failed to signature.", e);}
    }public boolean verify(byte[] data, byte[] key, byte[] sign)
    {try{PublicKey pubKey = this.toPubKey(key);Signature signature = Signature.getInstance(this.getSignatureAlg(), this.getProvider());signature.initVerify(pubKey);signature.update(data);return signature.verify(sign);}catch (Exception e){throw new EncryptionException("failed to verify signature.", e);}
    }
    
  • SM2加密批量验证逻辑

    @Test
    public void encrypt()
    {int[] encLengths = {256};super.encrypt(encLengths);
    }@Test
    public void testEncryptAndSign()
    {String initKey = UUID.randomUUID() + new String(RandomUtils.nextBytes(5000), StandardCharsets.UTF_8);int[] encLengths = {256};BaseSingleSignature encryption = new Sm2Encryption();for (int encLen : encLengths){encryption.setEncryptLen(encLen);KeyPair keyPair = encryption.createKey(initKey.getBytes(StandardCharsets.UTF_8));super.testEncryptAndSign(encryption, keyPair.getPrivate().getEncoded(), keyPair.getPublic().getEncoded());}
    }  
    

    说明:

    1. SM2可以不用设置加密长度,因为默认只有一个,同理我们也无需关心其填充算法;
    2. 通过单元测试对比RSA算法可知,SM2由于秘钥非常短,其秘钥生成和加解密效率明显高于RSA;

2. 总结:

  1. 基于BouncyCastleSM2由于其算法独特性,与其它的算法实现差异加大,但是在实际使用时,由于其秘钥非常短,在核心的加解密执行效率上是有一定优势的;
  2. SM2支持多种方式的秘钥生成,本开源组件较好地解决了秘钥不同方式生成的兼容问题;
  3. SM2算法相对来说还比较新,在有些秘改(国密改造)场景时,还无法做到。因为大部分开源组件只支持标准协议,一般支持p256v1非对称加密,但是不支持sm2p256v1,国人仍需努力。
http://www.yayakq.cn/news/250441/

相关文章:

  • 网站服务器位于北美安康电商网站建设
  • 自己做的网站出现乱码天元建设集团有限公司 李增启 电话
  • 网站建设备案 优帮云鞍山58路公交车路线
  • 开源的公司网站如何更改wordpress语言
  • 在线做GO分析的网站wordpress 3.3.1 漏洞
  • 浦东新区建设工程安全质量监督站网站深圳营销型网站建设推广服务
  • 网站建设推广哪家好东莞浩智专业网站建设哪家好
  • 社区网站设计策划书3000字可以做早安图片的网站
  • 泸州工投建设集团有限公司网站手工包网站建设策划书
  • 网站制作 网站建设 杭州做一个15页的网站怎么做
  • 新乡网站设计青岛网页建设
  • 厦门过路费网站成都科技网站建设咨询
  • 商城网站 搭建莆田百度seo排名
  • 商城网站平台自适应型网站建设多少钱
  • 商城网站设计说明书免费网站模板软件
  • 五金喷漆东莞网站建设2018年靖边建设项目招投标网站
  • qq是腾讯还是阿里seo推广代运营
  • rp做网站苏州招聘网站制作
  • 商贸有限公司网站案例网站制作 视频
  • 想买个服务器做网站免费婚恋网站设计
  • 河南省旅游网站建设从58做网站怎么做
  • 网站建设怎样接业务微网站设计与开发
  • 南阳企业网站建设公司做网站的难点是什么
  • 适合建设网站的国外服务器有创意的营销案例
  • 代码优化网站排名网站建设沈阳凯鸿
  • 用软件做的网站权限网站域名出售
  • 网站编辑做seo好做吗微信营销微网站建设
  • 网站如何制作多少钱wordpress安装主题之后首页不变
  • 申请建设网站的报告html5网站建设报价
  • 网站建设费放什么科目第三方平台推广引流