阅读 164

Java中的对称加密详解

大家好,本篇文章主要讲的是Java中的对称加密详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下

目录
  • 常见的对称加密方法

  • 代码案例

    • byte[] 和16进制字符串相互转换

    • DES 加密和解密

    • AES 加密和解密

    • 加密模式

    • 填充模式

    • 使用加密模式和填充模式的案例

  • 总结

    采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。

    常见的对称加密方法

    DES : Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。

    AES : Advanced Encryption Standard, 高级加密标准 .在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

    代码案例

    byte[] 和16进制字符串相互转换

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    private byte[] hexStringToBytes(String hexString) {
        if (hexString.length() % 2 != 0) throw new IllegalArgumentException("hexString length not valid");
        int length = hexString.length() / 2;
        byte[] resultBytes = new byte[length];
        for (int index = 0; index < length; index++) {
            String result = hexString.substring(index * 2, index * 2 + 2);
            resultBytes[index] = Integer.valueOf(Integer.parseInt(result, 16)).byteValue();
        }
        return resultBytes;
    }
    private String bytesToHexString(byte[] sources) {
        if (sources == null) return null;
        StringBuilder stringBuffer = new StringBuilder();
        for (byte source : sources) {
            String result = Integer.toHexString(source& 0xff);
            if (result.length() < 2) {
                result = "0" + result;
            }
            stringBuffer.append(result);
        }
        return stringBuffer.toString();
    }

    DES 加密和解密

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    private String encryptByDES(String input,String key) throws Exception {
        // 算法
        String algorithm = "DES";
        String transformation = "DES";
        // Cipher:密码,获取加密对象
        // transformation:参数表示使用什么类型加密
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定秘钥规则
        // 第一个参数表示:密钥,key的字节数组 长度必须是8位
        // 第二个参数表示:算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // 对加密进行初始化
        // 第一个参数:表示模式,有加密模式和解密模式
        // 第二个参数:表示秘钥规则
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 进行加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        return bytesToHexString(bytes);
    }
     
    private String decryptByDES(String input,String key)throws Exception{
        // 算法
        String algorithm = "DES";
        String transformation = "DES";
        // Cipher:密码,获取加密对象
        // transformation:参数表示使用什么类型加密
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定秘钥规则
        // 第一个参数表示:密钥,key的字节数组 长度必须是8位
        // 第二个参数表示:算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // 对加密进行初始化
        // 第一个参数:表示模式,有加密模式和解密模式
        // 第二个参数:表示秘钥规则
        cipher.init(Cipher.DECRYPT_MODE,sks);
        // 进行解密
        byte [] inputBytes = hexStringToBytes(input);
        byte[] bytes = cipher.doFinal(inputBytes);
        return new String(bytes);
     }

    AES 加密和解密

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    private String encryptByAES(String input,String key) throws Exception {
        // 算法
        String algorithm = "AES";
        String transformation = "AES";
        // Cipher:密码,获取加密对象
        // transformation:参数表示使用什么类型加密
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定秘钥规则
        // 第一个参数表示:密钥,key的字节数组 长度必须是16位
        // 第二个参数表示:算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // 对加密进行初始化
        // 第一个参数:表示模式,有加密模式和解密模式
        // 第二个参数:表示秘钥规则
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 进行加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        return bytesToHexString(bytes);
    }
     
    private String decryptByAES(String input,String key)throws Exception{
        // 算法
        String algorithm = "AES";
        String transformation = "AES";
        // Cipher:密码,获取加密对象
        // transformation:参数表示使用什么类型加密
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定秘钥规则
        // 第一个参数表示:密钥,key的字节数组 长度必须是16位
        // 第二个参数表示:算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // 对加密进行初始化
        // 第一个参数:表示模式,有加密模式和解密模式
        // 第二个参数:表示秘钥规则
        cipher.init(Cipher.DECRYPT_MODE,sks);
        // 进行解密
        byte [] inputBytes = hexStringToBytes(input);
        byte[] bytes = cipher.doFinal(inputBytes);
        return new String(bytes);
    }

    加密模式

    ECB


    Electronic codebook, 电子密码本. 需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密

    在这里插入图片描述

    优点:并行加密,速度快
    缺点:同样的明文,加密成同样的密文,容易被破解,不利于安全保护
    CBC

    在这里插入图片描述

    优点:同样的原文生成不同的密文
    缺点:串行处理,速度慢

    注意: 需要一个初始的向量值IV

    填充模式

    当需要按块处理的数据, 数据长度不符合块处理需求时, 按照一定的方法填充满块长的规则

    NoPadding
    不填充.
    在DES加密算法下, 要求原文长度必须是8byte的整数倍
    在AES加密算法下, 要求原文长度必须是16byte的整数倍PKCS5Padding
    数据块的大小为8位, 不够就补足

    注意
    默认情况下, 加密模式和填充模式为 : ECB/PKCS5Padding
    如果使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new IvParameterSpec(key.getBytes());

    加密模式和填充模式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    AES/CBC/NoPadding (128)
    AES/CBC/PKCS5Padding (128)
    AES/ECB/NoPadding (128)
    AES/ECB/PKCS5Padding (128)
    DES/CBC/NoPadding (56)
    DES/CBC/PKCS5Padding (56)
    DES/ECB/NoPadding (56)
    DES/ECB/PKCS5Padding (56)
    DESede/CBC/NoPadding (168)
    DESede/CBC/PKCS5Padding (168)
    DESede/ECB/NoPadding (168)
    DESede/ECB/PKCS5Padding (168)
    RSA/ECB/PKCS1Padding (1024, 2048)
    RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
    RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)

    使用加密模式和填充模式的案例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    private String encryptByAES(String input,String key) throws Exception {
        // 算法
        String algorithm = "AES";
        String transformation = "AES/CBC/PKCS5Padding";
        // Cipher:密码,获取加密对象
        // transformation:参数表示使用什么类型加密
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定秘钥规则
        // 第一个参数表示:密钥,key的字节数组 长度必须是16位
        // 第二个参数表示:算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // 初始向量值长度必须是16位
        String ivStr = "2222222222222221";
        IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
        // 对加密进行初始化
        // 第一个参数:表示模式,有加密模式和解密模式
        // 第二个参数:表示秘钥规则
        cipher.init(Cipher.ENCRYPT_MODE,sks,iv);
        // 进行加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        return bytesToHexString(bytes);
    }
     
    private String decryptByAES(String input,String key)throws Exception{
        // 算法
        String algorithm = "AES";
        String transformation = "AES/CBC/PKCS5Padding";
        // Cipher:密码,获取加密对象
        // transformation:参数表示使用什么类型加密
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定秘钥规则
        // 第一个参数表示:密钥,key的字节数组 长度必须是16位
        // 第二个参数表示:算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // 初始向量值长度必须是16位
        String ivStr = "2222222222222221";
        IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
        // 对加密进行初始化
        // 第一个参数:表示模式,有加密模式和解密模式
        // 第二个参数:表示秘钥规则
        cipher.init(Cipher.DECRYPT_MODE,sks,iv);
        // 进行解密
        byte [] inputBytes = hexStringToBytes(input);
        byte[] bytes = cipher.doFinal(inputBytes);
        return new String(bytes);
    }

    总结

    到此这篇关于Java中的对称加密详解的文章就介绍到这了

    原文链接:https://blog.csdn.net/shuzhuchengfu/article/details/122698107


    文章分类
    代码人生
    文章标签
    版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
    相关推荐