美文网首页程序员
java AES加密实现

java AES加密实现

作者: Cjiajiagame | 来源:发表于2020-02-26 21:37 被阅读0次

    最近我编程真的是走火入魔。更是对加密痴迷。最近整了个AES-CBC的加密算法,然后用它做了个GUI的加密界面。我不晒GUI,但是加密算法还是要说的~
    AES的CBC模式,总是比没有偏移量的ECB模式安全得多。实现方式并不难,只是多了个偏移量。
    注意!这里需要外部包org.apache.commons.codec.binary.Base64库,请去百度上搜索并下载!
    话不多说,进入标题。
    首先,为了能更好地运用模块,我们下面来了解一下:

    //需要的库:
    import javax.crypto.* 
    import javax.crypto.spec.* //以上两个是java原生的加密库
    import org.apache.commons.codec.binary.Base64 //Base64加密库
    ----------------
    SecretKeySpec(byte[] 密钥key, "AES") //是密钥的一个类
    IvParameterSpec(byte[] 偏移量IV) //是偏移量的一个类
    Cipher() //加密原生类。
    Cipher.getInstance("AES/CBC/PKCS5Padding") //获取Cipher的对象,与new一样。参数格式为:加密算法/加密模式/填码格式
    Cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec 密钥Key, IvParameterSpec 偏移量IV) //对Cipher对象做初始化。DECRYPT_MODE为解密模式,ENCRYPT_MODE为加密模式。
    Cipher.doFinal(byte[] 要加密或解密的字符串) //结束对Cipher对象的参数控制,加密或解密字符串并返回密文。(byte[])
    Base64().encodeToString(byte[] 要加密的字符串) //返回Base64加密的String字符串。
    Base64().decode(byte[] 要解密的字符串) //返回Base64解密后的byte[]字符串。
    

    如果密钥是空的、密钥不够长怎么办?那只好抛出错误。我自定义了错误类还写了一大堆throw,真是小题大做啊……
    下面是一个错误类的参考:

    public class NullKeyException extends Exception{ //几乎我自定义的三个类格式一模一样,只是名字和构造方法变了
        /**
         * 构建一个不带信息的异常。
         */
        public NullKeyException() {
        }
    
        /**
         * 构建一个带信息的异常。
         * @param msg 消息
         */
        public NullKeyException(String msg) {
            super(msg);
        }
    }
    //调用下列方法即可抛出错误:
    throw new NullKeyException();
    

    有了妥妥的参考,说不定就可以无师自通了。唯一的难点就是返回的字符串类型byte[]String容易混淆。他们是不可互通的。
    咱们把参数串起来,写一个Class

    public class CBC {
        private static String str = null, key = null, iv = null;
    
        /**
         * 构建一个新的AES-CBC加密对象。
         * @param STR 解密或加密的字符串
         * @param KEY 秘钥
         * @param IV 偏移量
         */
        public CBC(String STR, String KEY, String IV){
            str = STR;
            key = KEY;
            iv = IV;
        }
        /**
         * 随机获取一个秘钥。
         * @return 秘钥
         */
        public static final String GetKey(){//至于解决方法可以去百度一下的。
            String chars = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";
            StringBuffer value = new StringBuffer();
            for(int i = 0; i < 16; i++){
                value.append(chars.charAt((int) (Math.random()* 62)));
            }
            return value.toString();
        }
        /**
         * 随机获取一个偏移量。
         * @return 秘钥
         */
        public static final String GetIV(){//至于解决方法可以去百度一下的。
            String chars = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";
            StringBuffer value = new StringBuffer();
            for(int i = 0; i < 16; i++){
                value.append(chars.charAt((int) (Math.random()* 62)));
            }
            return value.toString();
        }
    
        /**
         * 加密字符串。
         * @return 正常则返回加密后的数据,秘钥、偏移量错误或其他错误均会被抛出。
         * @throws Exception 其他错误
         * @throws NullKeyException 秘钥为空
         * @throws NullIvException 偏移量为空
         * @throws KeyIvNotLengthyException 秘钥或偏移量的长度不够16位
         */
        public static String Encrypt() throws Exception,
                NullKeyException,
                NullIvException,
                KeyIvNotLengthyException{
            if(key == null) throw new NullKeyException();
            if(key.length() != 16) throw new KeyIvNotLengthyException("秘钥的长度不够16位");
            if(iv == null) throw new NullIvException();
            if(iv.length() != 16) throw new KeyIvNotLengthyException("偏移量(IV)的长度不够16位");
            byte[] raw = key.getBytes("utf-8");
            SecretKeySpec key_spec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec IV = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, key_spec, IV);
            byte[] encrypted = cipher.doFinal(str.getBytes());
            return new Base64().encodeToString(encrypted);
        }
    
    /**
     * 解密字符串。
     * @return 正常则返回解密后的数据,秘钥、偏移量错误或其他错误均会被抛出。
     * @throws Exception 其他错误
     * @throws NullKeyException 秘钥为空
     * @throws NullIvException 偏移量为空
     * @throws KeyIvNotLengthyException 秘钥或偏移量的长度不够16位
     */
    public static String Decrypt() throws Exception,
            NullKeyException,
            NullIvException,
            KeyIvNotLengthyException{
        if(key == null) throw new NullKeyException();
        if(key.length() != 16) throw new KeyIvNotLengthyException("秘钥的长度不够16位");
        if(iv == null) throw new NullIvException();
        if(iv.length() != 16) throw new KeyIvNotLengthyException("偏移量(IV)的长度不够16位");
        SecretKeySpec key_spec = new SecretKeySpec(key.getBytes("utf-8"), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec IV = new IvParameterSpec(iv.getBytes("utf-8"));
        cipher.init(Cipher.DECRYPT_MODE, key_spec, IV);
        byte[] encryptding = new Base64().decode(str);
        return new String(cipher.doFinal(encryptding));
    }
    

    }
    如果还是不理解的话,去我GITHUB上翻就可以了~
    我告诉你,你可别轻易转载!

    相关文章

      网友评论

        本文标题:java AES加密实现

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