美文网首页
加密算法 - 对称加密算法

加密算法 - 对称加密算法

作者: GTMYang | 来源:发表于2023-08-29 17:49 被阅读0次

一. 对称加密算法种类

密钥管理复杂,不适合互联网,一般用于内部系统;安全性中;加密速度极快,适合大数据量的加密处理;加解密的过程是可逆的。

名称 密钥名称 运行速度 安全性 资源消耗
DES 56位 较快
3DES 112位或168位
AES 128、192、256位
Blowfish
IDEA
RC5
RC6
  • DES算法:DES 加密算法是一种 分组密码,以 64 位为 分组对数据 加密,它的 密钥长度 是 56 位,加密解密 用 同一算法。DES 加密算法是对 密钥 进行保密,而 公开算法,包括加密和解密算法。这样,只有掌握了和发送方 相同密钥 的人才能解读由 DES加密算法加密的密文数据。因此,破译 DES 加密算法实际上就是 搜索密钥的编码。对于 56 位长度的 密钥 来说,如果用 穷举法 来进行搜索的话,其运算次数为 2 ^ 56 次。
  • 3DES算法:是基于 DES 的 对称算法,对 一块数据 用 三个不同的密钥 进行 三次加密,强度更高。
  • AES算法:AES 加密算法是密码学中的 高级加密标准,该加密算法采用 对称分组密码体制,密钥长度的最少支持为 128 位、 192 位、256 位,分组长度 128 位,算法应易于各种硬件和软件实现。这种加密算法是美国联邦政府采用的 区块加密标准。本身就为了取代DES的,具有更好的安全性、效率和灵活性。
@NotThreadSafe
public class AesHelper {
    private SecretKeySpec keySpec;
    private IvParameterSpec iv;
 
    public AesHelper(byte[] aesKey, byte[] iv) {
        if (aesKey == null || aesKey.length < 16 || (iv != null && iv.length < 16)) {
            throw new RuntimeException("错误的初始密钥");
        }
        if (iv == null) {
            iv = Md5Util.compute(aesKey);
        }
        keySpec = new SecretKeySpec(aesKey, "AES");
        this.iv = new IvParameterSpec(iv);
    }
 
    public AesHelper(byte[] aesKey) {
        if (aesKey == null || aesKey.length < 16) {
            throw new RuntimeException("错误的初始密钥");
        }
        keySpec = new SecretKeySpec(aesKey, "AES");
        this.iv = new IvParameterSpec(Md5Util.compute(aesKey));
    }
 
    public byte[] encrypt(byte[] data) {
        byte[] result = null;
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES/CFB/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            result = cipher.doFinal(data);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }
 
    public byte[] decrypt(byte[] secret) {
        byte[] result = null;
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES/CFB/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            result = cipher.doFinal(secret);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }
 
    public static byte[] randomKey(int size) {
        byte[] result = null;
        try {
            KeyGenerator gen = KeyGenerator.getInstance("AES");
            gen.init(size, new SecureRandom());
            result = gen.generateKey().getEncoded();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }
}

二. Cipher初始化时的 transformation ??

transformation:“算法/模式/填充”或“算法”

三. 对称加密的模式

  • GCM (Galois/Counter Mode)模式

  本质上是AES的CTR模式(计数器模式)加上GMAC(Galois Message Authentication Code, 伽罗华消息认证码)进行哈希计算的一种组合模式。GCM可以提供对消息的加密和完整性校验,另外,它还可以提供附加消息的完整性校验。
  GMAC(Galois Message Authentication Code/伽罗瓦消息验证码)
GMAC是一种MAC算法,利用伽罗华域(Galois Field,GF,有限域)乘法运算来计算消息的 MAC 值。

  • ECB 电子密码本模式 Electron Code Book

  这种模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密

  • CBC 加密块链模式 Cipher Block Chaining

  CBC 模式的加密首先也是将明文分成固定长度的块,然后将前面一个加密块输出的密文与下一个要加密的明文块进行异或操作,将计算的结果再用密钥进行加密得到密文。
  第一明文块加密的时候,因为前面没有加密的密文,所以需要一个初始化向量。跟ECB 方式不一样,通过连接关系,使得密文跟明文不再是一一对应的关系,破解起来更困难,而且克服了只要简单调换密文块可能达到目的的攻击。

  • CFB 加密反馈模式 Cipher Feedb ack Mode

  面向字符应用程序的加密要使用流加密算法,可以使用加密反馈模式进行加密。在此模式下,数据用更小的单元加密,如可以是8位,这个长度小于定义的块长(通常是 64 位)。
  要点:数据分组,数据块更小。64位向量左移8位,再补上上轮所得的密文高8(c)位。密钥和向量加密得k,k高8位与明文异或得到下一轮的密文。
  优点:分组密码转化为流模式,隐藏了明文模式,可以及时加密传送小于分组的数据。
  缺点:密文不利于并行计算,如果一个明文单元损坏,则会影响多个密文单元,需要唯一的初始化向量。

  • OFB 输出反馈模式 Output Feedback Mode

  输出反馈模式与 CFB 相似,惟一差别是,CFB 中密文填入加密过程下一阶段,而
  在 OFB 中,初始化向量加密过程的输入填入加密过程下一阶段。
  要点:数据分组,数据块更小(这里取8bit)。64位向量左移8位,再补上上轮所得的k高8(c)位。密钥和向量加密得k。k高8位与明文异或得到下一轮的密文。
  优点:分组密码转化为流模式,隐藏了明文模式,可以及时加密传送小于分组的数据。
  缺点:密文不利于并行计算,如果一个明文单元损坏,则会影响多个密文单元,且对明文的主动攻击是可能的。

  • CTR计数器模式

  CTR(Counter, 计数器)模式是另外一种序列密码;分组密码的输入为一个计数器。初始化输入(IV)必须谨慎选择,防止重复;

四. 对称加密填充算法

  • PKCS7算法

假定分组加密的块长度为BlockSize, 明文字节数组长度为SrcSize, 则按下面的公式计算padding。padding即是明文需要补位的字节数,也是补位的每个字节的数值,解密时通过最后一个字节的数值判断需要去除多少个填充字节。
padding = BlockSize - SrcSize % BlockSize
padding的值范围是[1, BlockSize],即最小值为1,最大值为BlockSize。BlockSize支持的取值范围是[1, 255]。目前主流的对称加密算法的BlockSize是16,如AES与SM4。
举例说明:
假设BlockSize为16,那么:
如果padding为1,就在明文尾部填充1个1;
如果padding为13,就在明文尾部填充13个13;
如果padding为16,就在明文尾部填充16个16;
特别注意,padding为16代表明文长度正好是16的整数倍,但此时仍然在明文尾部补充16个16,这样在解密时就仍然是通过最后一个字节的数值来判断需要去掉多少个填充的字节,而不需要对明文长度正好是16整数倍的情况做特殊处理。

  • PKCS5算法

PKCS5是PKCS7的子集,BlockSize值固定为8,其他规则一样。
目前PKCS5基本不再使用,因为主流的AES与SM4的BlockSize都是16。

  • NoPadding 不使用填充算法

五. 参考

对称加密算法的四种模式以及优缺点
常见对称加密算法与工作模式简介
密码学 - 加解密算法 - 加解密模式
老程序员密码学笔记
官方参考文档

相关文章

网友评论

      本文标题:加密算法 - 对称加密算法

      本文链接:https://www.haomeiwen.com/subject/czvgmdtx.html