基于Java Cipher封装通用对称加密、非对称加密、数字信封

背景:与第三方交互经常会使用加密、验签等安全策略。有的加密工具由第三方提供,有的提供算法等参数自己开发,为减少加密等功能的开发工作量,决定封装一个通用的加解密工具。

1. 名词解释

1.1. 对称加密

加密和解密使用统一密钥,AES、DES、3DES等

  • 优点:简单快捷,密钥较短,破译困难
  • 缺点:使用同一密钥,需要将密钥公布给第三方,实际安全性受损

1.2. 非对称加密

加解密使用不同密钥,如RSA

  • 优点:双方交换公钥(私钥保密)后能避免由于密钥公布带来的安全性受损,操作规范(只有按照规范执行才能保证安全性):加密用对方公钥,解密用己方私钥;签名用己方私钥,验签用对方公钥;
  • 缺点:加解密比对称加密耗时、对数据有长度限制

1.3. 数字信封

结合对称加密和非对称加密的特性,具体步骤:

  1. 随机生成一个对称加密密钥
  2. 使用第一步的密钥加密数据
  3. 非对称加密第一、二步的对称密钥
  4. 非对称加密过的密钥对称加密的密文数据一起发送给对方

1.4. 工作模式

ECB

电子密码本模式:Electronic codebook,是最简单的块密码加密模式,加密前根据加密块大小(如AES为128位)分成若干块,之后将每块使用相同的密钥单独加密,解密同理

CBC

密码分组链接模式:Cipher-block chaining,由IBM于1976年发明,每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块。同时,为了保证每条消息的唯一性,在第一个块中需要使用初始化向量IV

1.5. 填充方式

对不满足一个整块(block)的部分进行填充的方式。

常见填充方式:

  • PKCS7Padding
  • PKCS5Padding
  • NoPadding(无填充,需要自己处理)

2. java中的密码器

2.1. 密码器Cipher

Java底层实现了常见的加密算法,使用Cipher类,仅需要传入相应算法参数即可轻松实现加密。

Cipher常用类方法:

方法名 作用 参数说明
Cipher getInstance(String algorithm) 获取密码器实例 algorithm:算法/工作模式/填充方式
void init(int MODE, Key key,AlgorithmParameterSpec iv) 初始化密码器 MODE:Cipher.ENCRYPT_MODE:加密/Cipher.DECRYPT_MODE:解密;
key:密钥;
iv:偏移量(CBC模式需要)
byte[] doFinal(byte[] data) 计算,加密/解密(根据init的MODE参数) data:呆加密的密文

2.2. 密钥工具Key

Key接口表示密钥,其子接口PublicKeyPrivateKey分别表示公钥和私钥

获取Key的方式:

  • 生成
    • 对称加密:KeyGenerator
    • 非对称加密:KeyPairGenerator
  • 还原
    • 对称加密:new SecretKeySpec(byte[] keyBytes,String keyAlgorithm)
    • 非对称加密:使用KeyFactory类,由于要还原,需要使用KeySpec 的子类EncodedKeySpecEncodedKeySpec中含有构造函数EncodedKeySpec(byte[] encodedKey)
      • 私钥:generatePrivate(KeySpec keySpec)KeySpec 具体类型:PKCS8EncodedKeySpec
      • 公钥:generatePublic(KeySpec keySpec)KeySpec 具体类型:X509EncodedKeySpec

2.3. 签名器Signature

签名工具Signature使用相当简单,代码中signAlgorithm为签名算法,如SHA1withRSA

// 1.获取实例
Signature signature = Signature.getInstance(signAlgorithm)

// 2.签名
// 	2.1.初始化
signature.initSign(privateKey);
// 	2.2.装填数据
signature.update(data);
// 	2.3.签名
signature.sign();

// 3. 验签
// 	3.1.初始化
signature.initVerify(publicKey);
// 	3.2.装填数据
signature.update(data);
// 	3.3.验签
signature.verify(verify);

3. 封装思路

目标:

  • 实现传入"算法/工作模式/填充方式"即可使用(CBC工作模式set偏移量)
  • 密钥长度应该是有默认,且可选的
  • 使用签名只需要set签名算法

思路:

  1. Cipher类加解密计算入参和响应都是byte[],至于怎样转成字符串(Hex,Base64)不关心。
  2. CBC工作模式需要使用偏移量iv初始化密码器,固初始化密码器的代码需要判断模式。
  3. 对称加密和非对称加密使用的Key不一致,所以要分开封装对称加密、非对称加密、数字信封。
  4. 分别封装对称加密和非对称加密后,再将两者合并为数字信封。

你可能感兴趣的:(IT技术)