zoukankan      html  css  js  c++  java
  • 使用java库中的对称加密算法

    对称加密算法是说加密方和解密方使用相同的密钥.常见的对称加密算法包括4个,DES,DESede(3DES),AES,PBE.

    本文讨论的内容是加密算法,不是Message Digest,不是编码.下面区分一下这三个概念.

    加密算法是一对一映射,明文密文一一对应.加密是不明确的,是隐晦的.

    信息摘要是一个密文对应多个明文,它只是明文整体的一个指纹,一个反映,一个摘要.

    编码是一对一映射,是明确的,是显然易见的,比如base64编码.

    一.DES(Data Encryption Standard)

    DES(Data Encryption Standard)名叫数据加密标准.它明文分成64位一组分块加密,密钥也是64位.其中,密钥的第7,15,23,31,39,47,56,63位是为了凑成奇校验位(保证一个字节中1的个数为奇数个),所以密钥实际有效位数是56位.

    java中的DES可以如下调用:

    public class DES {
        private final static String KEY_DES = "DESede";
        static String tos(byte[] b) {
            String ans = "";
            for (int i = 0; i < b.length; i++) {
                ans += String.format("%02X", b[i]);
            }
    
            return ans;
        }
        public static void main(String[] args)
                throws NoSuchAlgorithmException, InvalidKeyException,
                NoSuchPaddingException, InvalidKeySpecException,
                IllegalBlockSizeException, BadPaddingException {
            SecureRandom secure = new SecureRandom("weidiao".getBytes());;
            KeyGenerator generator = KeyGenerator.getInstance(KEY_DES);
            generator.init(secure);
            byte[] key = generator.generateKey().getEncoded();
            // DESKeySpec dks = new DESKeySpec(key);
            // SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_DES);
            // SecretKey secretKey = factory.generateSecret(dks);
            // 上述三行代码与下面这行代码等效,但是上面代码只适用于DES,而下面的代码可以适用于很多其它加密方式
            // 实际上,下面这行代码会自动调用上述代码
            SecretKeySpec secretKey = new SecretKeySpec(key, KEY_DES);
            byte[] data = "123".getBytes();
            Cipher cipher = Cipher.getInstance(KEY_DES);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encrypt = cipher.doFinal(data);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decrypt = cipher.doFinal(encrypt);
            System.out.println("密钥: " + tos(key));
            System.out.println("原始数据: " + tos(data));
            System.out.println("加密后: " + tos(encrypt));
            System.out.println("解密后:" + tos(decrypt));
        }
    }

    二.DESede(DES encrypt-decrypt-encrypt)

    DESede又名3DES,它并不是一种新的加密算法,而是在DES的基础上多运算了几次,使得加密效果更好,如果破解它需要花费原来三倍的时间.它充分利用了DES的可逆性,即充分利用了DES的明文密文为一对一映射.

    DESede中的e表示加密,d表示解密,实际上3DES算法如下所示,e表示加密函数,d表示解秘函数,一共用到3对加解密密钥:

    encrypt=e3(d2(e1(data)))

    decrypt=d1(e2(d3(encrypt)))

    将上述DES代码中的KEY_DES改成"DESede"即可运行DESede加密算法.

    三.AES(Advanced Encryption Standard)

    AES(高级加密标准)是为了替代DES(数据加密标准)而出现的.AES 设计有三个密钥长度:128,192,256 位。相对而言,AES 的 128 密钥比 DES 的 56 位密钥强了 1021 倍。WPA(无线局域网受保护访问协议)是一种新型的无线安全技术,它的实现就采用了AES加密.

    将上述DES代码中的KEY_DES改成"AES"即可运行AES加密算法.

    四.PBE(Password Base Encryption)

    PBE算法是一个集大成者,它能够将消息摘要算法和对称加密算法整合起来.

    前面说的DES,3DES,AES都是只需要一个密钥就能够进行加密,有人说这个密钥太难记了,能不能用用户密码作为密钥?试想如果有人知道了你的密码,什么加密都是没有用的,他们可以直接用你的密码进行登录,加密过程只能挡住想偷盗密码的人却不能挡住已经偷到密码的人.所以,用用户密码作为密钥是可行的.别人得不到你的密钥等价于别人得不到你的密码,这就是用密码作为密钥的合理性.

    那么问题来了,密码通常很短,而上述DES和3DES需要64位公钥,AES需要128位公钥(还有更长的公钥).解决方法是用MD5或者SSHA将密码进行消息摘要,这样一来就可以将密码弄成固定长度了.所以PBE算法有如下几种类型:

    • PBEWithSHAAndDES
    • PBEWithSHAAndBlowfish
    • PBEWithSHAAnd128BitRC4
    • PBEWithSHAAndIDEA-CBC
    • PBEWithSHAAnd3-KeyTripleDES-CBC

    如果害怕密码被试探出来,可以加点盐.PBE算法是支持加盐的,但是加盐之后的PBE需要把盐作为密钥.这样跟上面AES,DES,3DES之流又有何分别?所以对于这个算法加盐并无卵用,反倒破坏了它本身的优势----除了密码没有密钥,还是要把密码设置的复杂些,防止被试探出来.

    PBE的优点是不需要来回传输密钥了,简单容易记忆.它的缺点正是它的优点,因为如果入侵者通过抓包抓到了密文,就算他不知道密码,也依旧能够使用密文进行登录,因为密码并不总是变.也就是说,密钥最好只能用一次.如果密钥固定,那就跟密码没有差别了.

  • 相关阅读:
    C# 一个数组集合,任意组合,不遗漏,不重复
    C# 对象遍历 string类型 null转空字符串和去前后空格
    mysql中varchar可以存多少汉字
    ping ipconfig telnet
    mysql 生成UUID() 即 ORACLE 中的guid()函数
    a标签的href和onclick
    JQuery设置checkbox选中或取消等相关操作
    JS eval()函数
    ztree设置节点checked,选中某节点等相关操作
    Windows数据库定时备份
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/5922325.html
Copyright © 2011-2022 走看看