AES

Posted xingminghui111

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AES相关的知识,希望对你有一定的参考价值。

 

数据块:128位/192位/256位
密钥长度问题 默认 Java 中仅支持 128 位密钥,当使用 256 位密钥的时候,会报告密钥长度错误 Invalid AES key length 你需要下载一个支持更长密钥的包.这个包叫做 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6

经过10轮循环的状态矩阵中的内容就是加密后的密文 https://www.bbsmax.com/A/gAJGZBGXzZ/

PRNG 是一种伪随机数生成器,它一般都是使用特定的随机种子,根据某个特定的算法生成伪随机序列,通常用于给其他加解密算法提供种子。
Java SecureRandom 两种伪随机数算法( SHA1PRNG 与 NativePRNG )
SHA1PRNG 实现原理是通过不断对当前Hash值进行再一次SHA1哈希而成,当给定种子的情况下,每次输出都是基于上次的结果

 

    public static void main(String[] args) {
        try {
//            String en =  encrypt("abcdefg","1234567");
//            out.println(en);
//            String de = decrypt("56f2f5b288f03beb3826c764d5b1b403","1234567");
//            out.println(de);

//            String en =  encrypt("abcdefg","1234567");
//            out.println(en);
//            String de = decrypt("VvL1sojwO+s4Jsdk1bG0Aw==","1234567");
//            out.println(de);


        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //密文展示形式 Base64展示 与 16位字符串展示
    public static String encrypt(String a,String key)  throws Exception{
        byte[] content = a.getBytes("UTF-8");
        byte[] keyBytes = key.getBytes("UTF-8");
        byte[] encryptText = getCipher(keyBytes, Cipher.ENCRYPT_MODE).doFinal(content);
        String s = parseByte2HexStr(encryptText);
//        String s = encodeBase64(encryptText).replace(" ", "");
        return s;
    }

    public static String decrypt(String a,String key) throws Exception{

        byte[] content =parseHesStr2Byte2(a);
//        byte[] content =decodeBase64(a);
        byte[] keyBytes = key.getBytes("UTF-8");
        byte[] originBytes = getCipher(keyBytes, Cipher.DECRYPT_MODE).doFinal(content);
        return  new String(originBytes,"utf-8");
    }


    private static Cipher getCipher(byte[] key,int mode) throws Exception{
        Cipher cipher = null;
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        //SHA1是PRNG算法的一种  其他算法NativePRNG  Java SecureRandom 两种伪随机数算法( SHA1PRNG 与 NativePRNG )
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");//设置算法 使用散列函数和计数器
        secureRandom.setSeed(key);
        kgen.init(128,secureRandom);//使用用户提供的password初始化此密钥生成器,使其具有确定的密钥大小128字节长
        SecretKey secretKey = kgen.generateKey();

        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
        cipher = Cipher.getInstance("AES");// 创建密码器
        cipher.init(mode, secretKeySpec);
        return  cipher;
    }

    //转换为16进制字符串
    private static String parseByte2HexStr(byte buf[]) throws Exception{
        StringBuffer sb = new StringBuffer();
        for (byte aByte : buf) {
            String s=Integer.toHexString(0xff & aByte);
            if(s.length()==1){
                sb.append("0"+s);
            }else{
                sb.append(s);
            }
        }
        return sb.toString();
    }

    private static byte[] parseHesStr2Byte(String hexstring){
        byte[] destByte = new byte[hexstring.length()/2];
        for(int i=0;i<destByte.length;i++) {
            int high = Integer.parseInt(hexstring.substring(i*2,i*2+1),16);
            int low = Integer.parseInt(hexstring.substring(i*2+1,i*2+2),16);
            destByte[i]=(byte)(high*16+low);
        }
        return  destByte;
    }

    private static byte[] parseHesStr2Byte2(String hexstring){
        out.println(2);
        byte[] destByte = new byte[hexstring.length()/2];
        int j=0;
        for(int i=0;i<destByte.length;i++) {
            byte high = (byte) (Character.digit(hexstring.charAt(j),16) & 0xff);
            byte low = (byte) (Character.digit(hexstring.charAt(j + 1),16) & 0xff);
            destByte[i] = (byte) (high << 4 | low);
            j+=2;
        }
        return destByte;
    }




    private static String encodeBase64(byte[] input) throws Exception {
        Class clazz = Class
                .forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
        Method mainMethod = clazz.getMethod("encode", byte[].class);
        mainMethod.setAccessible(true);
        Object retObj = mainMethod.invoke(null, new Object[] { input });
        return (String) retObj;
    }
    private static byte[] decodeBase64(String input) throws Exception {
        Class clazz = Class
                .forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
        Method mainMethod = clazz.getMethod("decode", String.class);
        mainMethod.setAccessible(true);
        Object retObj = mainMethod.invoke(null, input);
        return (byte[]) retObj;
    }

}

  

 

以上是关于AES的主要内容,如果未能解决你的问题,请参考以下文章

Go-AES算法详解与代码

为什么Crypto ++中的AES代码会产生不同的性能结果?

更新实现代码对称加密与解密剖析:AES,高级加密标准(Advanced Encryption Standard,缩写AES)

QT:AES-256-CBC 根据 PHP 代码在 C++ 中加密/解密

AES加密解密代码

Java aes加密C#解密的取巧方法