Java之对称加密

对称加密

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

常见的对称加密方法

  • DES : Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。
  • AES : Advanced Encryption Standard, 高级加密标准 .在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

代码案例

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

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 加密和解密

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 加密和解密

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());

加密模式和填充模式

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)

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

    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);
    }
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值