<dependency>
<groupId>com.biuqugroupId>
<artifactId>bq-encryptorartifactId>
<version>1.0.1version>
dependency>
如3.2.1
分层设计的包名规划图所示,除了加密算法
(XxxEncryption
)外,其它的封装皆为SpringBoot
准备,可以非常方便的注入其中,使用也及其简单;
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
中注入加密机
:@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
:@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微服务基础框架
中开源。
本节将从国际标准的加密分类、加解密组件的分层、加解密组件的使用、加解密组件的实现依次予以介绍。
名称 | 全称 | 类型 | 加密长度 |
加密/工作模式/填充模式 | 签名算法 | 使用场景 | 典型案例 |
---|---|---|---|---|---|---|---|
RSA | 3人名缩写 | 非对称加密 | 2048 |
- RSA/ECB/PKCS1Padding RSA/ECB/OAEPWithSHA-1AndMGF1Padding RSA/ECB/OAEPWithSHA-256AndMGF1Padding |
SHA512WITHRSA SHA256WITHRSA … |
加密效率较低,一般不用作加密 用做签名 |
HTTPS证书 JwtToken签名 |
SM2 | SM2椭圆曲线公钥密码算法 | 非对称加密 | 256 | - | SM3WithSM2 | 安全性优于RSA 2048,可用于替代RSA 用做签名 |
国产HTTPS证书 国产加密机 |
AES | Advanced Encryption Standard | 对称加密 | 256 |
AES/CBC/NoPadding AES/CBC/PKCS5Padding AES/ECB/PKCS5Padding AES/CTR/NoPadding |
- | 加密效率高,当下只有256位是安全的 通常使用CBC/CTR模式加密 |
各种数据加密 |
SM4 | SM4分组密码算法 | 对称加密 | 128 |
SM4/CBC/PKCS5Padding SM4/CTR/NoPadding |
- | 安全性优于AES 256,可用于替换AES 通常使用CBC/CTR模式加密 |
各种数据加密 |
3DES | Triple Data Encryption Algorithm | 对称加密 | 192 |
DESede/CBC/NoPadding DESede/CBC/PKCS5Padding DESede/ECB/PKCS5Padding |
- | 安全性较差,建议使用AES/SM4来替代 | 各种数据加密 |
SHA-1 | Secure Hash Algorithm 1 | 摘要算法 | 160 |
- | - | - 用于内容防篡改 | 各种报文/下载文件的完整性校验 |
SHA-256 | Secure Hash Algorithm 2 | 摘要算法 | 256 |
- | - | - 用于内容防篡改 | 各种报文/下载文件的完整性校验 |
SHA-512 | Secure Hash Algorithm 2 | 摘要算法 | 512 |
- | - | - 用于内容防篡改 | 各种报文/下载文件的完整性校验 |
SHA3 | Secure Hash Algorithm 3 | 摘要算法 | 512 |
- | - | - 用于内容防篡改 | 各种报文/下载文件的完整性校验 |
SM3 | SM3密码杂凑算法 | 摘要算法 | 256 |
- | - | 在SHA-256基础上的改进算法,用于替代SHA算法 | 各种报文/下载文件的完整性校验 |
Secure Hash Algorithm 1 | 摘要算法 | - | - | 用于内容防篡改 | 安全性较差,建议使用SHA-512/SM3来替替代 | ||
HmacSHA256 | Hash-based Message Authentication Code | 基于摘要的带认证码的加密算法 | 256 |
- | - | 用于内容防篡改 用于消息认证 |
安全性一般,曾用于早期的JwtToken认证 |
HmacSHA512 | Hash-based Message Authentication Code | 基于摘要的带认证码的加密算法 | 512 |
- | - | 用于内容防篡改 用于消息认证 |
Hmac-SHA256的升级版 |
HmacSM3 | Hash-based Message Authentication Code | 基于摘要的带认证码的加密算法 | 256 |
- | - | 用于内容防篡改 | Hmac的国产实现,用于替代HmacSHA256 |
加密长度
: 在加密算法中通常是指分段秘钥的长度,在摘要算法中通常是指内容块的长度;
补充说明
: 由于加密长度、填充模式、签名算法的不同,实际上会有非常多的组合使用方式,此处并没有一一列举,但组件基本上都已支持;
加密算法 加密器 加密机
+-------------+ +-------------+ +-------------+
| encryption | | encryptor | | hsm |
| | --------> | | --------> | |
+-------------+ +-------------+ | +-------------+
|
| 加密安全器
| +-------------+
| | security |
+----> | |
+-------------+
加密算法
(encryption
):提供了基本的加解密算法能力,包括生成秘钥,传入报文和秘钥做加解密,还提供了部分证书解析和转换的能力。包名:com.biuqu.encryption
;
加密器
(encryptor
):加密算法的封装类,简化了加解密算法的使用,初始化加密器时,就需要初始化秘钥,仅需要传入报文做加解密,包名:com.biuqu.encryptor
;
加密机
(hsm
):加密器的子类,封装了只需要在系统内部使用秘钥的、安全等级最高的加密器的使用,仅需要传入报文做特定的加解密,包名:com.biuqu.hsm
;
加密安全器
(security
):加密器的子类,封装了需要与外部交换秘钥、内部安全等级不高的特殊的加密器的使用,仅需要传入报文做加解密,包名:com.biuqu.security
;
加密机
(hsm
)和加密安全器
(security
)2种模式,因为很少需要在运行过程中去生成秘钥。bq-encryptor按照加解密算法类型划分 | |||||
---|---|---|---|---|---|
类型 | 抽象类 | 算法名称 | 算法实现类 | 是否安全 | 补充说明 |
对称加密算法 | BaseSingleEncryption | AES | AesEncryption | ✔ | 只有256位是安全的 |
SM4 | Sm4Encryption | ✔ | AES256的国内替代算法 | ||
3DES | Des3Encryption | ✖ | 不安全算法,不推荐使用 | ||
BaseSecureSingleEncryption | AES | AesSecureEncryption | ✔ | 在AES加解密时增加了盐值 | |
SM4 | Sm4SecureEncryption | ✔ | 在SM4加解密时增加了盐值 | ||
非对称加密算法 | BaseSingleSignature | RSA | RsaEncryption | ✔ | 只有2048位是安全的 |
SM2 | Sm2Encryption | ✔ | RSA2048的国内替代算法 | ||
复合加密算法 | BaseMultiEncryption | PGP | PgpEncryption | ✔ | 一般单独使用签名场景,加解密时效率也高于单独使用相同的非对称加密算法 在国际上有使用该协议做敏感报文的加解密 |
复合签名算法 | BaseMultiSignature | US | UsEncryption | ✔ | 自定义算法,综合使用了RSA2048/SHA512/AES256算法 |
GM | GmEncryption | ✔ | 自定义国密算法,综合使用了SM2/SM3/SM4算法 | ||
UsHsm | UsHsmEncryption | ✔ | 自定义算法,应用于加密机场景,综合使用了RSA2048/SHA512 | ||
GmHsm | GmHsmEncryption | ✔ | 自定义国密算法,应用于加密机场景,综合使用了SM2/SM3 | ||
摘要算法 | BaseHash | SHA-512 | ShaHash | ✔ | SHA摘要算法的通用实现,可支持:SHA-1/SHA-224/SHA-256/SHA-384/SHA-512/SHA3-224/SHA3-256/SHA3-384/SHA3-512/MD5等 |
SM3 | Sm3Hash | ✔ | SHA256的国内替代算法 | ||
HMAC算法 | KeyHash | HMAC | ShaHmacKeyHash | ✔ | HMAC的通用实现,可支持:HmacSHA1/HmacSHA224/HmacSHA256/HmacSHA384/HmacSHA512/HmacMD5等 |
Sm3Hmac | Sm3HmacKeyHash | ✔ | HMAC的国内替代算法 |
盐值
:即对应加解密算法中的偏移量;复合签名算法
:GM
/US
加密算法为业务场景中的提炼总结,GmHsm/UsHsm为加密机的实际使用经验总结,总之就是要兼顾加解密效率和安全;- 上述算法实现均基于BouncyCastle做了统一的封装;
- 国际加密算法基本上都有1个与之对应的国密算法(PGP除外);
EncryptionFactory
),可以非常快捷的创建任一个指定的加密算法对象;EncryptionFactory
构建3.2.2
表中的任意算法实现类并使用加解密,如: 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
表中任意算法对应的加密器并使用加解密,如: 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注入方式),如: 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注入方式),如: 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);
EncryptionFactory
汇聚了所有加解密算法的实现;EncryptorFactory
构建了所有加密器的实现(内置了加密算法和秘钥);SecurityFacade
构建了本地秘钥和安全要求不高的加解器的实现(除了内置加密算法和秘钥,还内置了一定的安全业务逻辑);HsmFacade
构建了安全极高的加密机的实现(除了内置加密算法和秘钥,且秘钥是无法被获取的,还内置了一定的安全业务逻辑);ClientSecurity
构建了本地秘钥和安全要求不高的加密器的实现(除了SecurityFacade
的作用外,还可以根据客户指定不同的秘钥);