DES加密算法的使用

最近项目在写工具类的时候用的加密解密算法是3DES,就总结一下DES-3DES-AES吧,按顺序来,先介绍下DES吧;

DES:是对称算法的以一种(加密、解密过程是可逆的,并且使用的密钥是一致的),关于加密算法的介绍,对称、非对称具体哪些,什么场景,大家可以翻看我之前的博客;

这里讲到加密解密算法,就简单说一下当下分组密码设计的两个原则混淆(confusion)和扩散(diffusion),其目的是抗击敌手对密码系统的统计分析。混淆是使密文的统计特性与密钥的取值之间的关系尽可能复杂化,以使密钥和明文以及密文之间的依赖性对密码分析者来说是无法利用的。扩散的作用就是将每一位明文的影响尽可能迅速地作用到较多的输出密文位中,以便在大量的密文中消除明文的统计结构,并且使每一位密钥的影响尽可能迅速地扩展到较多的密文位中,以防对密钥进行逐段破译。

而DES就基本符合这点;它把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位(实际用到了56位,第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1);

它的算法基本分两部,初始置换和逆置换;具体的看百科吧;https://baike.baidu.com/item/DES/210508?fr=aladdin 介绍的还可以;

上面介绍DES是分组设计,并且输入块是要分成64位的,如果目标串位数不够64的倍数,就要进行填充,这就涉及到了DES的填充模式,一般有两种;

NoPadding
API或算法本身不对数据进行处理,加密数据由加密双方约定填补算法。例如若对字符串数据进行加解密,可以补充\0或者空格,然后trim。

PKCS5Padding
加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8

这个项目里一般会填充,但JDK是有封装好的,在一些安全性要求没有很高的时候,默认情况下,JDK会帮你填充。

说到这,基本的理论差不多了,接下来上代码,怎么用DES呢?其实很简单,这里上一段简单的用例:

基本过程就是,根据所有的算法,和目标串,JDK的API获取密钥(注:密钥是随机的,不同加密,结果不同),然后进行加密解密,由于DES是对称算法,故加密解密几乎类似。下面看代码吧,不懂的可以看注释:

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class DES {
    /**
     * @param args the command line arguments
     */
    private static byte[] initKey() throws Exception{                             //获取密钥
        KeyGenerator keyGenerator=KeyGenerator.getInstance("DES");
        keyGenerator.init(56);
        SecretKey secretKey=keyGenerator.generateKey();
        return secretKey.getEncoded();
    }
    public static byte[] encryptDES(byte[] key,byte[] data) throws Exception{       //加密方法
        SecretKey secretKey=new SecretKeySpec(key,"DES");
        Cipher cipher=Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE,secretKey);
        byte[] resultBytes=cipher.doFinal(data);
        return resultBytes;
    }
    public static String decryptDES(byte[] key, byte[] data) throws Exception {      //解密方法
        SecretKey secretKey = new SecretKeySpec(key, "DES");
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] resultBytes = cipher.doFinal(data);
        return new String(resultBytes);
    }

    public static String bytesToHexString(byte[] src){    //将byte[]转化为16进制字符串
    StringBuilder stringBuilder = new StringBuilder("");   //将byte转换成int,然后利用Integer.toHexString(int)
    if (src == null || src.length <= 0) {                  //@param src byte[] data ;@return hex string 
        return null;  
    }  
    for (int i = 0; i < src.length; i++) {  
        int v = src[i] & 0xFF;  
        String hv = Integer.toHexString(v);  
        if (hv.length() < 2) {  
            stringBuilder.append(0);  
        }  
        stringBuilder.append(hv);  
    }  
    return stringBuilder.toString();  
}  
    public static void main(String[] args) throws Exception {         //测试
        // TODO code application logic here
        String data="helloworld";
        byte[] key=initKey();
        byte[] resultBytes=encryptDES(key,data.getBytes());
        String resultEncrypt=  bytesToHexString(resultBytes);
        System.out.println("加密:"+resultEncrypt);
        String resultDecrypt=decryptDES(key,resultBytes);
        System.out.println("解密:"+resultDecrypt);
    }
}

其实要破解 DES 加密过后的数据是完全有可能做到的,为什么呢?因为 DES 算法的密钥 也就64位,所有可能性加在一起也就是 2^64 次方。所以才有后面的3DES和AES,至于这个改天在说….睡觉要紧……

18.2.1;
上文中有个是字符转化为十六进制的函数,这里说下其中为什么要进行0xFF与操作,不知道你发现这个细节了吗?知道为什么吗?以为转十六进制是用Integer.toHexString,所以在byte转为int的时候,(涉及到计算机原理)Java中byte是8bit,int是32bit,在转换的时候会进行补位,而byte的范围是[-128,127],计算机负数是用补码表示,在补位事进行扩展后会发生变化,儿而oxff是默认的整形,与其做与运算会先将byte转化为整形运算,将补位清0;保证数值没变。

上面是插曲;继续说3DES和AES;

3DES 是在 DES 的基础上进行了改进,把密钥的长度加长了,可以是 112 位或者 168 位,这样密钥的可能性就增加到了 2^112 或者 2^168,也就不可能再被破解了,但是3DES 算法在增加密钥的同时也增加了迭代次数,这就会造成处理速度降低,加密效率比较低,是牺牲时间和性能来提高安全性。
AES 是高级加密标准,能够抵御已知的针对 DES 算法的所有攻击,而且相比于 3DES, 它的加密效率高,安全性能高。

AES 的加密模式和填充方式和 DES 是相同的,但是它的密钥有三种不同的长度,分别是 128(默认长度),192,256。不过需要注意的是,后两种长度的密钥默认状态下是不能使用的,只有在取得了相关政策权限才可以使用。

另外补充,MD5和SHA1是2种加密算法,用于计算出一段不可逆向计算的数值,以此来验证该文件是否被修改的,放篡改
数据完整性确认和数据来源的真伪鉴定都是很重要的安全服务。实现这些安全服务的最好方法就是使用加密函数中的单项散列(Hash)函数。单项散列(Hash)函数是一种单项密码体制,它是一个从明文到密文的不可逆函数,也就是说,是无法解密的。通常应用在只需要加密、不需要解密的特殊应用场合。
MD5和SHA的操作数量级不同,MD5是大概264数量级操作,而SHA是280,相对来说,增加的一系列的循环及操作,提高抗攻击性的同时,也增加了运行速度。
它可以帮你验证从网上下载下来的windows7安装程序是否与发布人发布的东西完全一致,也就是帮助你验证这个程序有没有经过他人(非发布人)的修改。
它们用的是单项散列,一种不可逆的函数。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魏小言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值