zoukankan      html  css  js  c++  java
  • AES、DES加解密方法(Java和JS编程)

    在项目中经常会对一些比较隐私的内容进行加密后再传输,比如登录密码、个人信息等;

    DES和AES是目前两种比较常用的对称加密算法;

    (此篇不讲原理,想了解原理可参考:DES算法AES算法

    一、JS实现方式:

    需要引入JavaScript加密库-CryptoJS

    1.DES加密以及解密:

     1 //DES 加密
     2 function encryptByDES(message, key) {
     3     var keyHex = CryptoJS.enc.Utf8.parse(key);
     4     var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
     5         mode: CryptoJS.mode.ECB,
     6         padding: CryptoJS.pad.Pkcs7
     7     });
     8     return encrypted.toString();
     9 }
    10 //DES 解密
    11 function decryptByDES(ciphertext, key) {
    12     var keyHex = CryptoJS.enc.Utf8.parse(key);
    13     // direct decrypt ciphertext
    14     var decrypted = CryptoJS.DES.decrypt({
    15         ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
    16     }, keyHex, {
    17         mode: CryptoJS.mode.ECB,
    18         padding: CryptoJS.pad.Pkcs7
    19     });
    20     return decrypted.toString(CryptoJS.enc.Utf8);
    21 }

    2.AES加密以及解密:

     1 //AES 加密
     2 function encryptByAES(message, key) {
     3     var keyHex = CryptoJS.enc.Utf8.parse(key);
     4     var encrypted = CryptoJS.AES.encrypt(message, keyHex, {
     5         mode: CryptoJS.mode.ECB,
     6         padding: CryptoJS.pad.Pkcs7
     7     });
     8     return encrypted.toString();
     9 }
    10 //AES 解密
    11 function decryptByAES(ciphertext, key) {
    12     var keyHex = CryptoJS.enc.Utf8.parse(key);
    13     // direct decrypt ciphertext
    14     var decrypted = CryptoJS.AES.decrypt({
    15         ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
    16     }, keyHex, {
    17         mode: CryptoJS.mode.ECB,
    18         padding: CryptoJS.pad.Pkcs7
    19     });
    20     return decrypted.toString(CryptoJS.enc.Utf8);
    21 }

    二、Java实现

    Java有两种AES加密实现方式:

    1.使用AES-128-ECB加密模式,秘钥必须为16位字符串(128bit = 16 * 8bit);这种方式与上面JS的AES可以前后端配合一起使用;

     1 // 加密
     2 public static String Encrypt(String sSrc, String sKey) throws Exception {
     3     if (sKey == null) {
     4         System.out.print("Key为空null");
     5         return null;
     6     }
     7     // 判断Key是否为16位
     8     if (sKey.length() != 16) {
     9         System.out.print("Key长度不是16位");
    10         return null;
    11     }
    12     byte[] raw = sKey.getBytes("utf-8");
    13     SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    14     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
    15     cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    16     byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
    17     //此处使用BASE64做转码功能,同时能起到2次加密的作用。
    18     //return new Base64().encodeToString(encrypted);
    19     return Base64.encode(encrypted);
    20 }
    21 
    22 // 解密
    23 public static String Decrypt(String sSrc, String sKey) throws Exception {
    24     try {
    25         // 判断Key是否正确
    26         if (sKey == null) {
    27             System.out.print("Key为空null");
    28             return null;
    29         }
    30         // 判断Key是否为16位
    31         if (sKey.length() != 16) {
    32             System.out.print("Key长度不是16位");
    33             return null;
    34         }
    35         byte[] raw = sKey.getBytes("utf-8");
    36         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    37         Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    38         cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    39         //先用base64转码
    40         //byte[] encrypted1 = new Base64().decode(sSrc);
    41         byte[] encrypted1 = Base64.decode(sSrc);
    42         try {
    43             byte[] original = cipher.doFinal(encrypted1);
    44             String originalString = new String(original,"utf-8");
    45             return originalString;
    46         } catch (Exception e) {
    47             System.out.println(e.toString());
    48             return null;
    49         }
    50     } catch (Exception ex) {
    51         System.out.println(ex.toString());
    52         return null;
    53     }
    54 }

    2.下面这种方式对加密解密的秘钥没有长度限制(代码中进行了补全到相应位数),但不能和JS的实现配合使用,将算法名称和秘钥的编码位数进行更改就变为了DES加密

     1 //加密
     2 public static String encrypt(String content, String password) {  
     3     try {
     4         //将秘钥补全为128位
     5         KeyGenerator kgen = KeyGenerator.getInstance("AES");
     6         //若想改为DES加密,则需要将秘钥位数改为64位
     7         kgen.init(128, new SecureRandom(password.getBytes()));
     8         SecretKey secretKey = kgen.generateKey();  
     9         byte[] enCodeFormat = secretKey.getEncoded();  
    10         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
    11         //创建密码器
    12         Cipher cipher = Cipher.getInstance("AES");
    13         byte[] byteContent = content.getBytes("utf-8");
    14         //初始化  
    15         cipher.init(Cipher.ENCRYPT_MODE, key);
    16         //加密 
    17         byte[] result = cipher.doFinal(byteContent);
    18         //Base64转码
    19         return Base64.encode(result); 
    20     } catch (NoSuchAlgorithmException e) {  
    21         e.printStackTrace();  
    22     } catch (NoSuchPaddingException e) {  
    23         e.printStackTrace();  
    24     } catch (InvalidKeyException e) {  
    25         e.printStackTrace();  
    26     } catch (UnsupportedEncodingException e) {  
    27         e.printStackTrace();  
    28     } catch (IllegalBlockSizeException e) {  
    29         e.printStackTrace();  
    30     } catch (BadPaddingException e) {  
    31         e.printStackTrace();  
    32     }  
    33     return null;
    34 }
    35 
    36 //解密
    37 public static String decrypt(String content, String password) throws Exception {  
    38     try {
    39         //将秘钥补全为128位
    40         KeyGenerator kgen = KeyGenerator.getInstance("AES");
    41         //若想改为DES加密,则需要将秘钥位数改为64位
    42         kgen.init(128, new SecureRandom(password.getBytes()));  
    43         SecretKey secretKey = kgen.generateKey();  
    44         byte[] enCodeFormat = secretKey.getEncoded();  
    45         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
    46         //创建密码器             
    47         Cipher cipher = Cipher.getInstance("AES");
    48         //初始化
    49         cipher.init(Cipher.DECRYPT_MODE, key);
    50         //Base64转码
    51         byte[] encrypted1 = Base64.decode(content);
    52         //解密
    53         byte[] result = cipher.doFinal(encrypted1);
    54         //二进制转为字符串
    55         return new String(result, "utf-8");
    56     } catch (NoSuchAlgorithmException e) {  
    57         e.printStackTrace();  
    58     } catch (NoSuchPaddingException e) {  
    59         e.printStackTrace();  
    60     } catch (InvalidKeyException e) {  
    61         e.printStackTrace();  
    62     } catch (IllegalBlockSizeException e) {  
    63         e.printStackTrace();  
    64     } catch (BadPaddingException e) {  
    65         e.printStackTrace();  
    66     }  
    67     return null;  
    68 }

     加密解密时密码器的输入输出都为2进制数组,这里我们用Base64在加解密的中间过程中进行了转码,所以可以以字符串形式展示加密后的密文,也可以使用下面的方法将二进制数组转换为16进制的字符串来表示,同样起到转换的作用

     1 //将二进制数组转化为16进制字符串
     2 public static String parseByte2HexStr(byte buf[]) {  
     3     StringBuffer sb = new StringBuffer();  
     4     for (int i = 0; i < buf.length; i++) {  
     5         String hex = Integer.toHexString(buf[i] & 0xFF);  
     6         if (hex.length() == 1) {  
     7             hex = '0' + hex;  
     8         }  
     9         sb.append(hex.toUpperCase());  
    10     }  
    11     return sb.toString();  
    12 }
    13 //将16进制字符串转化为二进制数组
    14 public static byte[] parseHexStr2Byte(String hexStr) {  
    15     if (hexStr.length() < 1)  
    16         return new byte[0];  
    17     byte[] result = new byte[hexStr.length()/2];  
    18     for (int i = 0;i< hexStr.length()/2; i++) {  
    19         int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);  
    20         int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);  
    21         result[i] = (byte) (high * 16 + low);  
    22     }  
    23     return result;  
    24 }

     源码下载

  • 相关阅读:
    9-单表查询
    02-数据库概述
    01-MySql的前戏
    mysql+centos7+主从复制
    Mac下安装ipython与jupyter
    python开发之virtualenv与virtualenvwrapper讲解
    python操作redis
    权限管理具体代码实现
    docker入门
    多用判断&&
  • 原文地址:https://www.cnblogs.com/Aoobruce/p/8243325.html
Copyright © 2011-2022 走看看