开源加解密组件bq-encryptor介绍

news/2024/7/10 20:56:14 标签: AES, RSA, SM2, SM4, java, 开源, PGP

bq-encryptor加解密组件说明

  • 支持RSA(1024/2048)/AES(128/192/256)/SHA-1/SHA-256/SHA-512/SHA-3/MD5/PGP/HMAC-SHA256/HMAC-SHA512等国际通用的加密算法;
  • 支持SM2/SM3/SM4/HMAC-SM3等国密算法;
  • 还支持国密和国际加密算法的统一抽象与封装,并封装了国际/国密组合使用的一些实践;
  • 加密组件引入方法:
    <dependency>
        <groupId>com.biuqu</groupId>
        <artifactId>bq-encryptor</artifactId>
        <version>1.0.1</version>
    </dependency>
    

1. 为什么要写bq-encryptor加解密组件

  • 密码学原理较复杂,但是应用阶段,绝大部分时候是不需要关注原理的。而网上一大堆内容在介绍原理,对于实现仅寥寥几笔,容易让涉足者望而却步,我想做到原理和应用隔离,让有兴趣的人快速上手怎么应用加解密;
  • 随着国密加解密算法崛起(基本上按照国际规范自研了1套),刚好可以按照抽象思维来实现2套加解密逻辑,有助于站在更高的位置、更好地理解各种加密算法的加解密特性;
  • 国密密改在政府、银行、金融保险行业有很高的安全诉求,在其他行业,也势在必行,此处也做了较好地模拟实现,以供参考;
  • 在Java世界里,当前使用最广泛的加解密组件莫过于BouncyCastle(澳大利亚非盈利组织)
    了,本加解密组件也是基于BouncyCastle做了二次封装,但是同时也屏蔽了其底层实现,期待着有一天我们也有自己的国产的更优实现;

2. 使用bq-encryptor加解密组件有什么好处

  • 3.2.1分层设计的包名规划图所示,除了加密算法(XxxEncryption)外,其它的封装皆为SpringBoot准备,可以非常方便的注入其中,使用也及其简单;

    • 在SpringBoot yaml中配置如下:
      bq:
        encrypt:
          #默认加密算法(true表示国密)
          gm: true
          #模拟的加密机(正常情况下,加密机的秘钥是在加密机服务中,此处是不用配置的)
          hsm:
            - algorithm: SM4Hsm
              pri: e9c9ba0326f00c39...
            - algorithm: SM2Hsm
              pri: 3081930201003013...
              pub: 3059301306072a8e...
            - algorithm: SM3Hsm
            - algorithm: GmIntegrityHsm
            - algorithm: AESHsm
              pri: 7c9726e56ce9bc28b...
            - algorithm: RSAHsm
              pri: 308204bc020100...
              pub: 30820122300d0...
            - algorithm: SHAHsm
            - algorithm: UsIntegrityHsm
          #经过加密机加密的jasypt秘钥
          enc: d83b8495e86...
          #经过jasypt加密的适用于本地加密和对外交互数据加密的加密器秘钥
          security:
            - algorithm: SecureSM4
              pri: ENC([key]f7222de...)
            - algorithm: SM4
              pri: ENC([key]5495204...)
            - algorithm: SM2
              pri: ENC([key]61835c8...)
              pub: ENC([key]0b74f34...)
            - algorithm: SM3
            - algorithm: GM
            - algorithm: SecureAES
              pri: ENC([key]6916ae6...)
            - algorithm: AES
              pri: ENC([key]a6b7ecd...)
            - algorithm: RSA
              pri: ENC([key]23708c8...)
              pub: ENC([key]c1ae5a5...)
            - algorithm: SHA-512
            - algorithm: US
            - algorithm: PGP
              pri: ENC([key]29ff6fa...)
              pub: ENC([key]c315ac7...)
              kid: pgpUser01
              pwd: ENC(e71aebdc7b5e...)
              expire: 33219557748024
              #自定义的加密器可以通过`- name:`来区分
    
    • SpringBoot中注入加密机
    java">@Configuration
    public class EncryptHsmConfigurer
    {
      @Bean("hsmBatchKey")
      @ConfigurationProperties(prefix = "bq.encrypt.hsm")
      public List<EncryptorKey> hsmBatchKey()
      {
          List<EncryptorKey> batchKey = new ArrayList<>(Const.TEN);
          return batchKey;
      }
    
      /**
       * 注入加密机的配置秘钥信息
       *
       * @return 加密机的配置秘钥信息
       */
      @Bean(EncryptorConst.HSM_KEYS)
      public EncryptorKeys hsmKeys(@Qualifier("hsmBatchKey") List<EncryptorKey> batchKey)
      {
          EncryptorKeys keys = new EncryptorKeys();
          keys.setKeys(batchKey);
          keys.setGm(this.gm);
          return keys;
      }
    
      /**
       * 注入加密机服务门面
       *
       * @param hsmKeys 加密机的配置秘钥信息
       * @return 加密机服务门面
       */
      @Bean(EncryptorConst.HSM_SERVICE)
      public HsmFacade hsmFacade(@Qualifier(EncryptorConst.HSM_KEYS) EncryptorKeys hsmKeys)
      {
          return new HsmFacade(hsmKeys);
      }
    
      /**
       * 注入业务安全服务
       *
       * @param hsmFacade 加密机服务
       * @return 业务安全服务
       */
      @Bean
      public BizHsmFacade hsmBizFacade(@Qualifier(EncryptorConst.HSM_SERVICE) HsmFacade hsmFacade)
      {
          return new BizHsmFacade(hsmFacade);
      }
    
      /**
       * 对配置文件中加密的默认类型(国密/国际加密)
       */
      @Value("${bq.encrypt.gm}")
      private boolean gm;    
    }
    
    • SpringBoot中注入jasypt
    java">@Configuration
    public class JasyptEncryptConfigurer
    { 
      /**
       * 配置自动加解密的处理器
       *
       * @return 加解密处理器
       */
      @Bean("jasyptStringEncryptor")
      public StringEncryptor getEncryptor()
      {
          String confKey = this.key;
          //兼容有加密机的场景(加密机会对配置文件的加密key进行加密)
          if (null != this.hsmFacade)
          {
              //解密出真实的配置key
              confKey = this.hsmFacade.decrypt(this.key);
          }
    
          BaseSecureSingleEncryption encryption;
          if (this.gm)
          {
              encryption = EncryptionFactory.SecureSM4.createAlgorithm();
          }
          else
          {
              encryption = EncryptionFactory.SecureAES.createAlgorithm();
          }
          return new JasyptEncryptor(encryption, confKey);
      }
    
      /**
       * 注入加密机(有才注入,否则忽略)
       */
      @Autowired(required = false)
      private HsmFacade hsmFacade;
    
      /**
       * 对配置文件是否为国密
       */
      @Value("${bq.encrypt.gm:true}")
      private boolean gm;
    
      /**
       * 对配置文件加密的sm4 key
       */
      @Value("${bq.encrypt.enc}")
      private String key;   
    }
    
    • SpringBoot中注入加密安全器,配置类同加密机的配置类,略。

    上述3个SpringBoot配置类简单说明了怎么批量注入加解密的对象,后续使用时,仅需通过注解就可以了。这些逻辑本人已全部实现并验证。此处仅了解整体的设计即可。

  • 可以支持多种业务场景:

    • 如上配置代码所示,可完美适配jasypt组件:支持模拟的加密机对jasypt组件的秘钥加密,再使用jasypt组件对加密安全器秘钥加密;
    • 支持加密机自动对数据库数据做数据加密和完整性校验;
    • 接口认证数据加密
    • 接口数据防篡改校验
    • 接口数据加密

    综上,上述业务场景的实现,本人会在后续的基于SpringCloud的bq微服务基础框架开源

3. bq-encryptor加解密组件的使用说明

本节将从国际标准的加密分类、加解密组件的分层、加解密组件的使用、加解密组件的实现依次予以介绍。

3.1 加解密分类

名称全称类型加密长度加密/工作模式/填充模式签名算法使用场景典型案例
RSA3人名缩写非对称加密1024
2048
- RSA/ECB/PKCS1Padding
RSA/ECB/OAEPWithSHA-1AndMGF1Padding
RSA/ECB/OAEPWithSHA-256AndMGF1Padding
SHA512WITHRSA
SHA256WITHRSA
加密效率较低,一般不用作加密
用做签名
HTTPS证书
JwtToken签名
SM2SM2椭圆曲线公钥密码算法非对称加密256-SM3WithSM2安全性优于RSA 2048,可用于替代RSA
用做签名
国产HTTPS证书
国产加密机
AESAdvanced Encryption Standard对称加密128
192
256
AES/CBC/NoPadding
AES/CBC/PKCS5Padding
AES/ECB/PKCS5Padding
AES/CTR/NoPadding
-加密效率高,当下只有256位是安全的
通常使用CBC/CTR模式加密
各种数据加密
SM4SM4分组密码算法对称加密128
SM4/CBC/PKCS5Padding
SM4/CTR/NoPadding
-安全性优于AES 256,可用于替换AES
通常使用CBC/CTR模式加密
各种数据加密
3DESTriple Data Encryption Algorithm对称加密192
DESede/CBC/NoPadding
DESede/CBC/PKCS5Padding
DESede/ECB/PKCS5Padding
-安全性较差,建议使用AES/SM4来替代各种数据加密
SHA-1Secure Hash Algorithm 1摘要算法160
--- 用于内容防篡改各种报文/下载文件的完整性校验
SHA-256Secure Hash Algorithm 2摘要算法256
--- 用于内容防篡改各种报文/下载文件的完整性校验
SHA-512Secure Hash Algorithm 2摘要算法512
--- 用于内容防篡改各种报文/下载文件的完整性校验
SHA3Secure Hash Algorithm 3摘要算法512
--- 用于内容防篡改各种报文/下载文件的完整性校验
SM3SM3密码杂凑算法摘要算法256
--在SHA-256基础上的改进算法,用于替代SHA算法各种报文/下载文件的完整性校验
MD5Secure Hash Algorithm 1摘要算法128<--用于内容防篡改安全性较差,建议使用SHA-512/SM3来替替代
HmacSHA256Hash-based Message Authentication Code基于摘要的带认证码的加密算法256
--用于内容防篡改
用于消息认证
安全性一般,曾用于早期的JwtToken认证
HmacSHA512Hash-based Message Authentication Code基于摘要的带认证码的加密算法512
--用于内容防篡改
用于消息认证
Hmac-SHA256的升级版
HmacSM3Hash-based Message Authentication Code基于摘要的带认证码的加密算法256
--用于内容防篡改Hmac的国产实现,用于替代HmacSHA256

加密长度: 在加密算法中通常是指分段秘钥的长度,在摘要算法中通常是指内容块的长度;

补充说明: 由于加密长度、填充模式、签名算法的不同,实际上会有非常多的组合使用方式,此处并没有一一列举,但组件基本上都已支持;

3.2 加解密组件的分层

3.2.1 分层整体设计

     加密算法                      加密器                        加密机
 +-------------+             +-------------+             +-------------+
 | encryption  |             |  encryptor  |             |     hsm     |
 |             |  -------->  |             |  -------->  |             |
 +-------------+             +-------------+     |       +-------------+
                                                 |
                                                 |           加密安全器
                                                 |       +-------------+
                                                 |       |   security  |
                                                 +---->  |             |
                                                         +-------------+

加密算法(encryption):提供了基本的加解密算法能力,包括生成秘钥,传入报文和秘钥做加解密,还提供了部分证书解析和转换的能力。包名:com.biuqu.encryption

加密器(encryptor):加密算法的封装类,简化了加解密算法的使用,初始化加密器时,就需要初始化秘钥,仅需要传入报文做加解密,包名:com.biuqu.encryptor

加密机(hsm):加密器的子类,封装了只需要在系统内部使用秘钥的、安全等级最高的加密器的使用,仅需要传入报文做特定的加解密,包名:com.biuqu.hsm

加密安全器(security):加密器的子类,封装了需要与外部交换秘钥、内部安全等级不高的特殊的加密器的使用,仅需要传入报文做加解密,包名:com.biuqu.security

  • 在实际的业务场景中,基本上只会使用加密机(hsm)和加密安全器(security)2种模式,因为很少需要在运行过程中去生成秘钥。

3.2.2 分层详细设计

  • 按照加解密算法类型划分
bq-encryptor按照加解密算法类型划分
类型抽象类算法名称算法实现类是否安全补充说明
对称加密算法BaseSingleEncryptionAESAesEncryption只有256位是安全的
SM4Sm4EncryptionAES256的国内替代算法
3DESDes3Encryption不安全算法,不推荐使用
BaseSecureSingleEncryptionAESAesSecureEncryptionAES加解密时增加了盐值
SM4Sm4SecureEncryptionSM4加解密时增加了盐值
非对称加密算法BaseSingleSignatureRSARsaEncryption只有2048位是安全的
SM2Sm2EncryptionRSA2048的国内替代算法
复合加密算法BaseMultiEncryptionPGPPgpEncryption一般单独使用签名场景,加解密时效率也高于单独使用相同的非对称加密算法
在国际上有使用该协议做敏感报文的加解密
复合签名算法BaseMultiSignatureUSUsEncryption自定义算法,综合使用了RSA2048/SHA512/AES256算法
GMGmEncryption自定义国密算法,综合使用了SM2/SM3/SM4算法
UsHsmUsHsmEncryption自定义算法,应用于加密机场景,综合使用了RSA2048/SHA512
GmHsmGmHsmEncryption自定义国密算法,应用于加密机场景,综合使用了SM2/SM3
摘要算法BaseHashSHA-512ShaHashSHA摘要算法的通用实现,可支持:SHA-1/SHA-224/SHA-256/SHA-384/SHA-512/SHA3-224/SHA3-256/SHA3-384/SHA3-512/MD5等
SM3Sm3HashSHA256的国内替代算法
HMAC算法KeyHashHMACShaHmacKeyHashHMAC的通用实现,可支持:HmacSHA1/HmacSHA224/HmacSHA256/HmacSHA384/HmacSHA512/HmacMD5等
Sm3HmacSm3HmacKeyHashHMAC的国内替代算法
  1. 盐值:即对应加解密算法中的偏移量;
  2. 复合签名算法GM/US加密算法为业务场景中的提炼总结,GmHsm/UsHsm为加密机的实际使用经验总结,总之就是要兼顾加解密效率和安全;
  3. 上述算法实现均基于BouncyCastle做了统一的封装;
  4. 国际加密算法基本上都有1个与之对应的国密算法(PGP除外);
  • 加密算法的简化使用设计
    • 使用工厂+枚举类的方式(参见EncryptionFactory),可以非常快捷的创建任一个指定的加密算法对象;
    • GM加密算法是综合了多个加密算法对象,做了封装实现:
      • 使用SM3对源报文生成摘要;
      • 使用自持的SM2私钥对摘要签名;
      • 使用新生成的SM4秘钥对源报文加密并生成密文;
      • 再使用对端的SM2公钥对SM4秘钥加密生成加密秘钥;
      • 拼接加密秘钥、签名和密文;
      • GM解密是上述步骤的逆过程;
    • US加密算法实现原理同上;
    • GmHsm加密算法是加密机的最佳实践总结:
      • 使用加密机的SM3对源报文生成摘要;
      • 使用加密机的私钥对摘要做签名;
      • GmHsm解密就是对源报文生成的摘要做验签;
    • UsHsm加密算法实现原理同上;

3.3 bq-encryptor加解密组件的使用

  • 使用EncryptionFactory构建3.2.2表中的任意算法实现类并使用加解密,如:
    java">    Sm2Encryption sm2 = EncryptionFactory.SM2.createAlgorithm();
        SecureRandom random = sm2.createRandom(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
        byte[] sm2InitKey = new byte[16];
        random.nextBytes(sm2InitKey);  
    
        String text = "testTextAbc`123";
        KeyPair keyPair = sm2.createKey(sm2InitKey);
        byte[] pubKey = keyPair.getPublic().getEncoded();
        byte[] priKey = keyPair.getPrivate().getEncoded();
        byte[] encryptBytes = sm2.encrypt(text.getBytes(StandardCharsets.UTF_8), pubKey, null);
        byte[] decryptBytes = sm2.decrypt(encryptBytes, priKey, null);
        System.out.println("Decrypt text=" + new String(decryptBytes, StandardCharsets.UTF_8));
    
  • 使用EncryptorFactory构建3.2.2表中任意算法对应的加密器并使用加解密,如:
    java">    EncryptorKey sm2Key = new EncryptorKey();
        sm2Key.setAlgorithm(EncryptorFactory.SM2.getAlgorithm());
        sm2Key.setPri(Hex.toHexString(keyPair.getPrivate().getEncoded()));
        sm2Key.setPub(Hex.toHexString(keyPair.getPublic().getEncoded()));
    
        Sm2Encryptor sm2Encryptor = EncryptorFactory.SM2.createEncryptor(sm2Key);
        byte[] encryptBytes = sm2Encryptor.encrypt(text.getBytes(StandardCharsets.UTF_8), null);
        byte[] decryptBytes = sm2Encryptor.decrypt(encryptBytes, null);
        System.out.println("Decrypt text=" + new String(decryptBytes, StandardCharsets.UTF_8));      
    
  • 使用SecurityFacade构建3.2.2表中任意算法对应的业务安全加密器并使用加解密(亦可参见第2章的SpringBoot注入方式),如:
    java">    List<EncryptorKey> keys = new ArrayList<>(32);
        keys.add(sm2Key);
    
        SecurityFacade securityFacade = new SecurityFacade(keys);
        String encryptText = securityFacade.signEncrypt(text);
        String decryptText = securityFacade.signDecrypt(encryptText);
        System.out.println("Decrypt text=" + decryptText);        
    
  • 使用HsmFacade构建3.2.2表中任意算法对应的加密机并使用加解密(亦可参见第2章的SpringBoot注入方式),如:
    java">    List<EncryptorKey> keys = new ArrayList<>(32);
        keys.add(sm2Key);
    
        HsmFacade hsmFacade = new HsmFacade(keys);
        String signText = hsmFacade.sign(text);
        boolean result = hsmFacade.verify(text,signText);
        System.out.println("verify result=" + result);      
    

3.4 bq-encryptor加解密组件的实现

  • EncryptionFactory汇聚了所有加解密算法的实现;
  • EncryptorFactory构建了所有加密器的实现(内置了加密算法和秘钥);
  • SecurityFacade构建了本地秘钥和安全要求不高的加解器的实现(除了内置加密算法和秘钥,还内置了一定的安全业务逻辑);
  • HsmFacade构建了安全极高的加密机的实现(除了内置加密算法和秘钥,且秘钥是无法被获取的,还内置了一定的安全业务逻辑);
  • ClientSecurity构建了本地秘钥和安全要求不高的加密器的实现(除了SecurityFacade的作用外,还可以根据客户指定不同的秘钥);
  • 后续会基于各种加密算法分别详细分析与总结;

http://www.niftyadmin.cn/n/346766.html

相关文章

Android Studio SDK无法勾选安装的解决方案

问题描述 1、在初次安装好Android Studio后&#xff0c;会启动AS&#xff0c;出现经典的Unable to access Android SDK add-on list报错&#xff0c;点Cancel即可。网上的解决方法分为两种&#xff1a;&#xff08;1&#xff09;设置Proxy为教育网&#xff08;2&#xff09;在…

人工智能专栏第十一讲——指代消歧

指代消歧是自然语言处理领域的一个重要问题,指的是在文本中确定代词所指的具体对象。在日常生活中,人们经常使用代词来替代前面出现过的名词,以避免重复,提高表达效率。但是,在处理自然语言文本时,计算机往往难以准确地理解代词所指的对象,因此需要进行指代消歧来解决这…

目标检测复盘 --3. Fast RCNN

RCNN的CNN部分使用AlexNet作为backbone来提取特征&#xff0c;Fast RCNN使用了VGG16来作为backboneRCNN将2000个框送入网络提取特征&#xff0c;Fast RCNN是将图像送入CNN来提取特征得到一个特征图将SS(Selective Search)算法获取的提议框映射到上面的特征图上&#xff0c;获取…

【校园网设计】基于ensp的跨地区的校园网组网方案

本博客是基于模拟器ensp的校园网组网方案&#xff0c;有总校区和分校区&#xff0c;主要用了vlan划分、dhcp、nat、ospf、acl、bgp等技术。首先说一下本博客的局限性&#xff1a; 总校区和分校区之间只是使用的传统的bgp建立连接&#xff0c;这样可以在运营商上看到内网的明细&…

PDF怎么添加水印?简单途径说明

在工作中&#xff0c;我们经常需要对PDF文档进行保护&#xff0c;以确保其不被未经授权的人员查看或修改。其中一种常见的保护方式是在PDF文件中添加水印。水印不仅可以保护文件的安全性&#xff0c;还可以帮助识别文档的来源以及保护版权。在本文中&#xff0c;我们将介绍如何…

基于Java+SpringBoot+vue+element实现校园疫情防控系统详细设计和实现

基于JavaSpringBootvueelement实现校园疫情防控系统详细设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源…

前端之CSS常用选择器分享~

目录 1. 标签选择器 2. 类选择器 3. id选择器 4. 后代选择器 5. 子代选择器 6. 并集选择器 7. 兄弟选择器 1. 标签选择器 ● 基本格式 : 标签名{属性1: ; 属性2: ; 属性3: ;....} ● 示例代码 <body><style>div {width: 100px;height: 100px;background-co…

小航助学GESP_C++一级模拟测试试卷(含题库答题软件账号)

GESP在线模拟训练系统请点击 电子学会-全国青少年编程等级考试真题Scratch一级&#xff08;2019年3月&#xff09;在线答题_程序猿下山的博客-CSDN博客_小航答题助手 答案:A 第1题人们在使用计算机时所提到的 Windows 通常指的是&#xff08;&#xff09;。 A、操作系统B、多…