博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASE加、解密
阅读量:7180 次
发布时间:2019-06-29

本文共 9716 字,大约阅读时间需要 32 分钟。

AES已经变成目前对称加密中最流行算法之一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据。

 

/**     * 加密     *     * @param content 需要加密的内容     * @param password  加密密码     * @return     */    public static byte[] encrypt(String content, String password) {        try {            KeyGenerator kgen = KeyGenerator.getInstance("AES");    //创建AES的key生产者            kgen.init(128, new SecureRandom(password.getBytes()));  //利用用户密码作为随机码初始化         //使其具有确定的128个字节的密钥大小,SecureRandom是生成安全随机数序列,        //password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行            SecretKey secretKey = kgen.generateKey();    //根据用户密码生成密钥            byte[] enCodeFormat = secretKey.getEncoded();  //返回基本编码格式的密钥,如果此密钥不支持编码,返回null            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");  //根据给定的字节数组构造一个为AES专用密钥            Cipher cipher = Cipher.getInstance("AES");    // 创建密码器            byte[] byteContent = content.getBytes("utf-8");            cipher.init(Cipher.ENCRYPT_MODE, key);      // 初始化为加密模式            byte[] result = cipher.doFinal(byteContent);            return result; // 加密        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        } catch (NoSuchPaddingException e) {            e.printStackTrace();        } catch (InvalidKeyException e) {            e.printStackTrace();        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        } catch (IllegalBlockSizeException e) {            e.printStackTrace();        } catch (BadPaddingException e) {            e.printStackTrace();        }        return null;    }

  

  

  

注意:解密的时候要传入byte数组

/**解密     * @param content  待解密内容     * @param password 解密密钥     * @return     */    public static byte[] decrypt(byte[] content, String password) {        try {            KeyGenerator kgen = KeyGenerator.getInstance("AES");            kgen.init(128, new SecureRandom(password.getBytes()));            SecretKey secretKey = kgen.generateKey();            byte[] enCodeFormat = secretKey.getEncoded();            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");            Cipher cipher = Cipher.getInstance("AES");// 创建密码器            cipher.init(Cipher.DECRYPT_MODE, key);// 初始化            byte[] result = cipher.doFinal(content);            return result;         } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        } catch (NoSuchPaddingException e) {            e.printStackTrace();        } catch (InvalidKeyException e) {            e.printStackTrace();        } catch (IllegalBlockSizeException e) {            e.printStackTrace();        } catch (BadPaddingException e) {            e.printStackTrace();        }        return null;    }

  

String content = "test";String password = "12345678";//加密System.out.println("加密前:" + content);byte[] encryptResult = encrypt(content, password);//解密byte[] decryptResult = decrypt(encryptResult,password);System.out.println("解密后:" + new String(decryptResult));

  

输出结果如下:
加密前:test
解密后:test
 

容易出错的地方

但是如果我们将测试代码修改一下,如下:
String content = "test";String password = "12345678";//加密System.out.println("加密前:" + content);byte[] encryptResult = encrypt(content, password);try {    String encryptResultStr = new String(encryptResult,"utf-8");    //解密    byte[] decryptResult = decrypt(encryptResultStr.getBytes("utf-8"),password);     System.out.println("解密后:" + new String(decryptResult));} catch (UnsupportedEncodingException e) {        e.printStackTrace();}
则,系统会报出如下异常:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
        at javax.crypto.Cipher.doFinal(DashoA13*..)
 
这主要是因为加密后的byte数组是不能强制转换成字符串的,换言之:字符串和byte数组在这种情况下不是互逆的;要避免这种情况,我们需要做一些修订,可以考虑将二进制数据转换成十六进制表示,主要有如下两个方
 
将二进制转换成16进制
**将二进制转换成16进制  * @param buf  * @return  */  public static String parseByte2HexStr(byte buf[]) {          StringBuffer sb = new StringBuffer();          for (int i = 0; i < buf.length; i++) {                  String hex = Integer.toHexString(buf[i] & 0xFF);                  if (hex.length() == 1) {                          hex = '0' + hex;                  }                  sb.append(hex.toUpperCase());          }          return sb.toString();  }

  

将16进制转换为二进制

/**将16进制转换为二进制  * @param hexStr  * @return  */  public static byte[] parseHexStr2Byte(String hexStr) {          if (hexStr.length() < 1)                  return null;          byte[] result = new byte[hexStr.length()/2];          for (int i = 0;i< hexStr.length()/2; i++) {                  int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);                  int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);                  result[i] = (byte) (high * 16 + low);          }          return result;  }

  

String content = "test";  String password = "12345678";  //加密  System.out.println("加密前:" + content);  byte[] encryptResult = encrypt(content, password);  String encryptResultStr = parseByte2HexStr(encryptResult);  System.out.println("加密后:" + encryptResultStr);  //解密  byte[] decryptFrom = parseHexStr2Byte(encryptResultStr);  byte[] decryptResult = decrypt(decryptFrom,password);  System.out.println("解密后:" + new String(decryptResult));

  

测试结果如下:
加密前:test
加密后:73C58BAFE578C59366D8C995CD0B9D6D
解密后:test

 

 

也可以使用BASE64进行包装处理。

加密bytes[] ----> passwordStr: new String(new BASE64Encoder().encode(doFinal))

 

解密String --->  new BASE64Decoder().decodeBuffer(passwordStr)

  

public static String generatePasswordAES2(String password, String passwordKey) {        try {            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");            keyGenerator.init(128, new SecureRandom(passwordKey.getBytes("UTF-8")));            SecretKey secretKey = keyGenerator.generateKey();            byte[] encoded = secretKey.getEncoded();            SecretKey key = new SecretKeySpec(encoded, "AES");            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");            System.out.println("密钥的长度为:" + key.getEncoded().length);            cipher.init(Cipher.ENCRYPT_MODE, key);            byte[] userPasswordBytes = password.getBytes("UTF-8");            byte[] doFinal = cipher.doFinal(userPasswordBytes);            String passwordBase64 = new String(new BASE64Encoder().encode(doFinal));            return passwordBase64;        } catch (Exception e) {            throw new BadRequestException("密码加密错误。");        }    }

  

public static String decryptPassword(String password, String token) {        try {            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");            keyGenerator.init(128, new SecureRandom(token.getBytes("UTF-8")));            SecretKey secretKey = keyGenerator.generateKey();            byte[] encoded = secretKey.getEncoded();            SecretKey key = new SecretKeySpec(encoded, "AES");            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");            cipher.init(Cipher.DECRYPT_MODE, key);            byte[] passwordBytes = new BASE64Decoder().decodeBuffer(password);            //解密            byte[] passwordDoFinal = cipher.doFinal(passwordBytes);            String decrypt = new String(passwordDoFinal, "UTF-8");            return decrypt;        } catch (Exception e) {            throw new BadRequestException("密码解密错误:" + e.getMessage());        }    }

  

 

AES-CBC-PKCS5

  

public static void main(String[] args)throws UnsupportedEncodingException {           Stringcontent="12345678";           Stringkey="abcdefgabcdefg12";           Stringiv="abcdefgabcdefg12";           //加密          byte[ ]encrypted=AES_CBC_Encrypt(content.getBytes(), key.getBytes(), iv.getBytes());          //解密          byte[ ]decrypted=AES_CBC_Decrypt(encrypted, key.getBytes(), iv.getBytes());                    System.out.println("解密后:"+byteToHexString(decrypted));         System.out.println(byteToString(decrypted));      }       public static String byteToString(byte[ ]byte1){           returnnew String(byte1);      }      public static byte[] AES_CBC_Encrypt(byte[]content, byte[] keyBytes, byte[] iv){                      try{               SecretKeySpec key = newSecretKeySpec(keyBytes, "AES");              Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");               cipher.init(Cipher.ENCRYPT_MODE,key, new IvParameterSpec(iv));               byte[]result=cipher.doFinal(content);              return result;          }catch (Exception e) {              System.out.println("exception:"+e.toString());           }            return null;       }              public static byte[] AES_CBC_Decrypt(byte[]content, byte[] keyBytes, byte[] iv){                      try{                    SecretKeySpec key = newSecretKeySpec(keyBytes, "AES");              Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");               cipher.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv));               byte[]result=cipher.doFinal(content);               return result;           }catch (Exception e) {               // TODO Auto-generated catchblock               System.out.println("exception:"+e.toString());           }            return null;       }   /**      * 字符串装换成base64      *       * @param key      * @return      * @throws Exception      */       public static byte[] decryptBASE64(Stringkey) throws Exception {            returnBase64.decodeBase64(key.getBytes());      }              /**      *二进制装换成base64      *       * @param key      * @return      * @throws Exception      */       public static String encryptBASE64(byte[]key) throws Exception {            returnnew String(Base64.encodeBase64(key));      }

  

转载于:https://www.cnblogs.com/skyLogin/p/6767640.html

你可能感兴趣的文章
直播热潮之下的图片社交洼地
查看>>
多地部署高考安防措施 严防在校大学生替考
查看>>
两周过去了,“想哭”勒索蠕虫近来可好?
查看>>
微软将于10月起禁用旧版Flash Player:Win8.1/10平台不受影响
查看>>
2017年网工必备8大技能
查看>>
国内车载信息安全产业联盟成立
查看>>
传微软2.5亿美元收购输入法应用SwiftKey
查看>>
向万物互联进发!中国电信智慧双创物联网示范基地启动
查看>>
赛门铁克警告Switch模拟器下载链接实为垃圾站点
查看>>
Facebook 为何要放弃辟谣?
查看>>
抓住“智慧城市”的机遇
查看>>
摩拜联手高通中移动 剑指最大物联平台步子太大?
查看>>
管理工具Meta SaaS完成150万美元融资,继续加强市场推广
查看>>
大数据,让知识成为一种服务
查看>>
二十款免费WiFi黑客(渗透测试)工具
查看>>
《嵌入式设备驱动开发精解》——第1章 关于本教程
查看>>
Aviator(表达式执行引擎)发布1.0.1
查看>>
海量高性能列式数据库HiStore技术架构解析
查看>>
Linux块设备驱动之内存模拟块设备
查看>>
「技术大牛」是如何缩短事件平均解决时间的?
查看>>