DES加密与3DES加密

作者: Y2136 | 来源:发表于2016-06-28 17:37 被阅读5082次

    DES

    数据加密标准(英语:Data Encryption Standard,缩写为 DES)是一种对称密钥加密块密码算法,1976年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),随后在国际上广泛流传开来。它基于使用56位密钥的对称算法。这个算法因为包含一些机密设计元素,相对短的密钥长度以及怀疑内含美国国家安全局(NSA)的后门而在开始时有争议,DES因此受到了强烈的学院派式的审查,并以此推动了现代的块密码及其密码分析的发展。

    DES现在已经不是一种安全的加密方法,主要因为它使用的56位密钥过短。1999年1月,distributed.net与电子前哨基金会合作,在22小时15分钟内即公开破解了一个DES密钥。也有一些分析报告提出了该算法的理论上的弱点,虽然在实际中难以应用。为了提供实用所需的安全性,可以使用DES的派生算法3DES来进行加密,虽然3DES也存在理论上的攻击方法。在2001年,DES作为一个标准已经被高级加密标准(AES)所替换。另外,DES已经不再作为国家标准科技协会(前国家标准局)的一个标准。

    在某些文献中,作为算法的DES被称为DEA(Data Encryption Algorithm,数据加密算法),以与作为标准的DES区分开来。在发音时,DES可以作为缩写按字母拼出来(/ˌdiːˌiːˈɛs/),或作为一个词念成/ˈdɛz/。
    DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。

    3DES

    密码学中,三重数据加密算法(英语:Triple Data Encryption Algorithm,缩写为TDEA,Triple DEA),或称3DES(Triple DES),是一种对称密钥加密块密码,相当于是对每个数据块应用三次数据加密标准(DES)算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

    DES有两种加密运算模式

    • CBC
      需要初始化向量IV,来加密第一块C0.
      有点就是比ECB好
      缺点不利于并行计算、误差会迭代,还需要初始向量
    • ECB
      优点就是简单,可以并行计算,不会迭代误差
      缺点就是隐藏不了模式

    填充模式

    • ZeroBytePadding
      所有需要填充的地方都以0填充。
    • PKCS7Padding java默认没有该填充方法
      填充的内容是需要填充的字节数。如果最后一个数据块长度为len,每个块的长度为k,则要填充的内容为:
         01 -- if lth mod k = k-1
         02 -- if lth mod k = k-2
         k k ..k k -- if lth mod k = 0
      需要注意的是,如果最后一个数据块的长度len恰好等于k,则需要在后面再添加一个完整的padding块,kk...kk。下面的例子是每8byte为一块,最后一块有8byte,需要填充8byte的\x08。
        ... | DD DD DD DD DD DD DD DD | DD DD DD DD DD DD DD DD | 08 08 08 08 08 08 08 08 |
    • PKCS5Padding
      PKCS5 和 PKCS7 的唯一区别是PKCS5只能用来填充64bit的数据块,除此之外可以混用。
    • NoPadding
      不填充,如果加密内容不是8字节整数倍加密则会报错
    • SSL3Padding

    C#的默认模式为CBC,默认填充方式为PKCS7
    java的默认模式为ECB,默认填充方式为PKCS5Padding
    C#中key的size为16和24均可
    java中要求key的size必须为24
    对于CBC模式下的向量iv的size两者均要求必须为8

    java平台每种加密方式所需密码长度

    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)
    
    import android.util.Log;
    
    import java.io.UnsupportedEncodingException;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    /**
     * 3DES加密解密
     * key长度为24个字符,不足可补零
     * IV向量必须为8位<br/>
     * 使用Base64.encodeToString(byte[], Base64.NO_WRAP);来将加密后的byte[]转为String<br/>
     * 使用Base64.decode(String, Base64.NO_WRAP);将转为String的加密字符转换为byte[]<br/>
     * new String(byte[])将解密后的byte[]转为String<br/>
     */
    public class DES3Util {
        private static final String TAG = "DES3Util";
        private static final String DES3 = "DESede";
    
        ///////////////////////////////////////////////////////////////////////////
        // DES3
        ///////////////////////////////////////////////////////////////////////////
    
        /**
         * 3DES ECB模式加密
         */
        public static byte[] des3EncodeECB(byte[] key, byte[] data) {
            try {
                SecretKey DESKey = new SecretKeySpec(key, DES3);    //生成密钥
                Cipher cipher = Cipher.getInstance(DES3 + "/ECB/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, DESKey);
                return cipher.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
                return null;
            }
        }
    
        /**
         * 3DES ECB模式解密
         */
        public static byte[] des3DecodeECB(byte[] key, byte[] data) {
            try {
                SecretKey DESKey = new SecretKeySpec(key, DES3);    //生成密钥
                Cipher cipher = Cipher.getInstance(DES3 + "/ECB/PKCS5Padding");
                cipher.init(Cipher.DECRYPT_MODE, DESKey);
                return cipher.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
                return null;
            }
        }
    
        /**
         * 3DES CBC模式加密
         */
        public static byte[] des3EncodeCBC(byte[] key, byte[] iv, byte[] data) {
            try {
                SecretKey DESKey = new SecretKeySpec(key, DES3);    //生成密钥
                Cipher cipher = Cipher.getInstance(DES3 + "/CBC/PKCS5Padding");
                IvParameterSpec ips = new IvParameterSpec(iv);
                cipher.init(Cipher.ENCRYPT_MODE, DESKey, ips);
                return cipher.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
                return null;
            }
        }
    
        /**
         * 3DES CBC模式加密
         */
        public static byte[] des3DecodeCBC(byte[] key, byte[] iv, byte[] data) {
            try {
                SecretKey DESKey = new SecretKeySpec(key, DES3);    //生成密钥
                Cipher cipher = Cipher.getInstance(DES3 + "/CBC/PKCS5Padding");
                IvParameterSpec ips = new IvParameterSpec(iv);
                cipher.init(Cipher.DECRYPT_MODE, DESKey, ips);
                return cipher.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
                return null;
            }
        }
    
        /**
         * 根据字符串生成密钥字节数组
         *
         * @param keyStr 密钥字符串
         */
        private static byte[] build3DesKey(String keyStr) {
            try {
                byte[] key = new byte[24];    //声明一个24位的字节数组,默认里面都是0
                byte[] temp = keyStr.getBytes("UTF-8");    //将字符串转成字节数组
                if (key.length > temp.length) {
                    //如果temp不够24位,则拷贝temp数组整个长度的内容到key数组中
                    System.arraycopy(temp, 0, key, 0, temp.length);
                } else {
                    //如果temp大于24位,则拷贝temp数组24个长度的内容到key数组中
                    System.arraycopy(temp, 0, key, 0, key.length);
                }
                return key;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
                return null;
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:DES加密与3DES加密

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