首页 > 代码库 > 浅谈DEs,AES

浅谈DEs,AES

1. AES加密,相对比较简单,之前已经配置好工具类。

package com.bbguoxue.poetry.util;import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;/** * AES加密器 * @author Eric_Ni * */public class AESEncryptor {    /**     * AES加密     */    public static String encrypt(String seed, String cleartext) throws Exception {          byte[] rawKey = getRawKey(seed.getBytes());          byte[] result = encrypt(rawKey, cleartext.getBytes());          return toHex(result);      }            /**     * AES解密     */    public static String decrypt(String seed, String encrypted) throws Exception {          byte[] rawKey = getRawKey(seed.getBytes());          byte[] enc = toByte(encrypted);          byte[] result = decrypt(rawKey, enc);          return new String(result);      }       private static byte[] getRawKey(byte[] seed) throws Exception {          KeyGenerator kgen = KeyGenerator.getInstance("AES");          SecureRandom sr = SecureRandom.getInstance("SHA1PRNG","Crypto");          sr.setSeed(seed);          kgen.init(128, sr); // 192 and 256 bits may not be available          SecretKey skey = kgen.generateKey();          byte[] raw = skey.getEncoded();          return raw;      }             private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {          SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");          Cipher cipher = Cipher.getInstance("AES");          cipher.init(Cipher.ENCRYPT_MODE, skeySpec);          byte[] encrypted = cipher.doFinal(clear);          return encrypted;      }       private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {          SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");          Cipher cipher = Cipher.getInstance("AES");          cipher.init(Cipher.DECRYPT_MODE, skeySpec);          byte[] decrypted = cipher.doFinal(encrypted);          return decrypted;      }       public static String toHex(String txt) {          return toHex(txt.getBytes());      }      public static String fromHex(String hex) {          return new String(toByte(hex));      }            public static byte[] toByte(String hexString) {          int len = hexString.length()/2;          byte[] result = new byte[len];          for (int i = 0; i < len; i++)              result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();          return result;      }       public static String toHex(byte[] buf) {          if (buf == null)              return "";          StringBuffer result = new StringBuffer(2*buf.length);          for (int i = 0; i < buf.length; i++) {              appendHex(result, buf[i]);          }          return result.toString();      }      private final static String HEX = "0123456789ABCDEF";      private static void appendHex(StringBuffer sb, byte b) {          sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));      }  }

这里要注意的是红色行,在android4.X的时候可能出席问题。很多地方都是写SecureRandow.getInstance("SHA1PRNG")

 

2. 使用DES加密

//这个现在有点怕了,也还半知半解

 private static final String DES_EDE     = "DESede/ECB/NoPadding";               //定义 加密算法,可用 DES,DESede,Blowfish        //keybyte为加密密钥,长度为24字节    //src为被加密的数据缓冲区(源)  
 
    private static final String DES_EDE_CBC = "DESede/CBC/NoPadding";               //定义 加密算法,可用 DES,DESede,Blowfish        //keybyte为加密密钥,长度为24字节    //src为被加密的数据缓冲区(源)  
 
    private static final String DES_CBC     = "DES/CBC/NoPadding";  
 
    private static final String DES_ECB     = "DES/ECB/PKCS5Padding";  

// 还有"DES/CBC/PKCS5Padding"------------android常用

加密说明: 算法/工作模式/填充

android可用模式,Ios去掉PKCS7Padding的方式得到的结果一样,能通用(Java中只能使用PKCS5Padding)

    private static String encrypt(byte[] raw, byte[] clear) throws Exception {        IvParameterSpec zeroIv = new IvParameterSpec(ivs);        SecretKeySpec skeySpec = new SecretKeySpec(raw, "DES");        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, zeroIv);        byte[] encrypted = cipher.doFinal(clear);        return toHex(encrypted);    }

//走的弯路

1. 类似AES那样生成密钥key。

2. 使用DESkey

        DESKeySpec dks = new DESKeySpec(raw);                SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");      //key的长度不能够小于8位字节        Key secretKey = keyFactory.generateSecret(dks);        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");        IvParameterSpec iv = new IvParameterSpec(new byte[8]);        AlgorithmParameterSpec paramSpec = iv;        cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);        return cipher.doFinal(clear);

得到的结果总不对。可以和上面的比较一下,这个使用了DESKeySpec,上面直接用的简单的SecretKeySpec。 本来也应该这样用的额,但互通性来说大家都简单的写了。

3. IvParameterSpec 这个类是很重要的, 这玩意是个初始化变量

很多地方可能使用示例new IvParamterSpec("12345678".getBytes()) ---------这其实在正常使用过程中常出现问题

很多都是用默认的{0,0,0,0,0,0,0,0}数组

 我的整个代码

import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;/** * AES加密器 *  * @author Eric_Ni * */public class AESEncryptor {    public static void main(String[] args) {        try {            System.out.println(encryptDES("123456", "dfardfsf"));            System.out.println(encrypt("dfardfsf", "123456"));            System.out.println(decrypt("dfardfsf", "B8CF276AF590D8B9"));        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    /**     * AES加密     */    public static String encrypt(String seed, String cleartext)            throws Exception {        return encrypt(seed.getBytes(), cleartext.getBytes());    }    /**     * AES解密     */    public static String decrypt(String seed, String encrypted)            throws Exception {        byte[] enc = toByte(encrypted);        byte[] result = decrypt(seed, enc);        return new String(result);    }    private static byte[] ivs = { 0, 0, 0, 0, 0, 0, 0, 0 };    public static String encryptDES(String encryptString, String encryptKey)            throws Exception {        IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);        SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");        cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);        byte[] encryptedData =http://www.mamicode.com/ cipher.doFinal(encryptString.getBytes());        return toHex(encryptedData);    }    private static String encrypt(byte[] raw, byte[] clear) throws Exception {        IvParameterSpec zeroIv = new IvParameterSpec(ivs);        SecretKeySpec skeySpec = new SecretKeySpec(raw, "DES");        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, zeroIv);        byte[] encrypted = cipher.doFinal(clear);        return toHex(encrypted);    }    private static byte[] decrypt(String raw, byte[] encrypted)            throws Exception {        SecretKeySpec skeySpec = new SecretKeySpec(raw.getBytes(), "DES");        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");        IvParameterSpec iv = new IvParameterSpec(ivs);        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);        return cipher.doFinal(encrypted);    }    public static String toHex(String txt) {        return toHex(txt.getBytes());    }    public static String fromHex(String hex) {        return new String(hex.getBytes());    }    public static byte[] toByte(String hexString) {        int len = hexString.length() / 2;        byte[] result = new byte[len];        for (int i = 0; i < len; i++)            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),                    16).byteValue();        return result;    }    public static String toHex(byte[] buf) {        if (buf == null)            return "";        StringBuffer result = new StringBuffer(2 * buf.length);        for (int i = 0; i < buf.length; i++) {            appendHex(result, buf[i]);        }        return result.toString();    }    private final static String HEX = "0123456789ABCDEF";    private static void appendHex(StringBuffer sb, byte b) {        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));    }}

 

JAVA中基本就只用这种了,如果需要使用其他的可以参考如下文章,未测试。

 

 

最后分享一下一位兄弟的总结,太多了没想去详细看

主要搞android,太复杂了还是用c做比较好点。不然容易被反编译

1.Base64  加密:org.apache.commons.codec.binary.Base64.encodeBase64(byte[] binaryData)  解密:org.apache.commons.codec.binary.Base64.decodeBase64(byte[] base64Data)2.Md5  加密:org.apache.commons.codec.digest.md5Hex(byte[] data)  解密:无3.DES(des-ecb,3des,des-cbc,cbc-mac)view plaincopy to clipboardprint? import java.io.ByteArrayOutputStream;  import java.security.SecureRandom;  import java.util.Arrays;   import javax.crypto.Cipher;  import javax.crypto.SecretKey;  import javax.crypto.SecretKeyFactory;  import javax.crypto.spec.DESKeySpec;  import javax.crypto.spec.DESedeKeySpec;  import javax.crypto.spec.IvParameterSpec;  import javax.crypto.spec.SecretKeySpec;   import org.bouncycastle.crypto.BlockCipher;  import org.bouncycastle.crypto.Mac;  import org.bouncycastle.crypto.engines.DESEngine;  import org.bouncycastle.crypto.macs.CBCBlockCipherMac;  import org.bouncycastle.crypto.params.KeyParameter;   import com.alibaba.common.lang.StringUtil;  import com.huateng.commons.lang.convert.HexUtils;   public class ShfftDes {      //验证用密钥      private byte[]              key         = "000000000000000000000000".getBytes();       //    private byte[]              key         = Hex.decode("00000000");       private byte[]              ivs         = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };       private static final String DES_EDE     = "DESede/ECB/NoPadding";               //定义 加密算法,可用 DES,DESede,Blowfish        //keybyte为加密密钥,长度为24字节    //src为被加密的数据缓冲区(源)       private static final String DES_EDE_CBC = "DESede/CBC/NoPadding";               //定义 加密算法,可用 DES,DESede,Blowfish        //keybyte为加密密钥,长度为24字节    //src为被加密的数据缓冲区(源)       private static final String DES_CBC     = "DES/CBC/NoPadding";       private static final String DES_ECB     = "DES/ECB/PKCS5Padding";            public byte[] CryptByDes(byte[] content, int mode) throws Exception {          Cipher cipher = Cipher.getInstance(DES_ECB);          SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");          SecretKey secretKey = keyFactory.generateSecret(new DESKeySpec(key));          cipher.init(mode, secretKey);          return cipher.doFinal(content);      }            public byte[] CryptBy3Des(byte[] content, int mode) throws Exception {          Cipher cipher = Cipher.getInstance(DES_EDE);          SecretKey secretKey = new SecretKeySpec(key, "DESede");          cipher.init(mode, secretKey);          return cipher.doFinal(content);      }            public byte[] CryptByDesCbc(byte[] content, int mode) throws Exception {          Cipher cipher = Cipher.getInstance(DES_CBC);          SecretKey secureKey = new SecretKeySpec(key, "DES");          IvParameterSpec iv = new IvParameterSpec(ivs);          cipher.init(mode, secureKey, iv);          return cipher.doFinal(HexUtils.fromHex(new String(content)));      }            public byte[] CryptBy3DesCbc(byte[] content, int mode) throws Exception {          Cipher cipher = Cipher.getInstance(DES_EDE_CBC);          SecretKey secureKey = new SecretKeySpec(key, "DESede");          IvParameterSpec iv = new IvParameterSpec(ivs);          cipher.init(mode, secureKey, iv);          return cipher.doFinal(content);      }            public byte[] CryptByDesCbcMac(byte[] content) throws Exception {          BlockCipher engine = new DESEngine();          Mac mac = new CBCBlockCipherMac(engine, 64);          byte[] macText = new byte[engine.getBlockSize()];          mac.init(new KeyParameter(key));          mac.update(Padding(content, 64), 0, content.length);          mac.update(content, 0, content.length);          mac.doFinal(macText, 0);          return macText;      }            public byte[] ShFftCryptByDessdsCbc(byte[] content, int mode) throws Exception {          byte[] ks1 = HexUtils.fromHex(new String(key));          byte[] ks = new byte[24];          System.arraycopy(ks1, 0, ks, 0, ks1.length);          System.arraycopy(ks1, 0, ks, ks1.length, 8);           Cipher cipher = Cipher.getInstance(DES_EDE_CBC);          SecretKeyFactory keyFactory = null;          keyFactory = SecretKeyFactory.getInstance("DESede");          SecretKey secretKey = null;          secretKey = keyFactory.generateSecret(new DESedeKeySpec(ks));          IvParameterSpec iv = new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 });          cipher.init(mode, secretKey, iv);          return cipher.doFinal(HexUtils.fromHex(new String(content)));      }       public byte[] mac(byte[] content) throws Exception {          int len;          byte plainData[];          byte encryptedData[];          len = (content.length / 8 + (content.length % 8 != 0 ? 1 : 0)) * 8;          plainData = new byte[len];          encryptedData = new byte[8];          Arrays.fill(plainData, (byte) 32);          System.arraycopy(content, 0, plainData, 0, content.length);          SecureRandom sr = new SecureRandom();          DESKeySpec dks = new DESKeySpec(key);          SecretKeyFactory keyFactory = null;          keyFactory = SecretKeyFactory.getInstance("DES");          SecretKey secretKey = keyFactory.generateSecret(dks);          Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");          IvParameterSpec iv = new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 });          cipher.init(1, secretKey, iv, sr);          System.arraycopy(cipher.doFinal(plainData), len - 8, encryptedData, 0, 8);          return encryptedData;      }            public byte[] Padding(byte[] content, int block) {          int contentLength = content.length;          int mod = contentLength % block;          if (mod != 0) {              int size = contentLength + block - mod;              //            String s = new String(content);              //            StringUtil.alignLeft(s, size, " ");              byte[] s = new byte[size];              System.arraycopy(content, 0, s, 0, content.length);              for (int i = content.length; i < size; i++) {                  s[i] = 32;              }              return s;          }          return content;      }            public String Padding(String content, int block) {          int contentLength = content.length();          int mod = contentLength % block;          if (mod != 0) {              int size = contentLength + block - mod;              String s = new String(content);              StringUtil.alignLeft(s, size, " ");              return s;          }          return content;      }            public void println(byte[] bs) {          for (byte b : bs) {              System.out.print(b + " ");          }          System.out.println();      }            public void printlnByte(byte[] bs) {          for (byte b : bs) {              if (b < 0) {                  System.out.print((int) b + 256 + " ");              } else {                  System.out.print(b + " ");              }          }          System.out.println();      }            public void printlnByteInt16(byte[] bs) {          for (byte b : bs) {              System.out.print(Integer.toHexString((int) b) + " ");          }          System.out.println();      }            public String dumpBytes(byte[] bytes) {          int i;          StringBuffer sb = new StringBuffer();          for (i = 0; i < bytes.length; i++) {              int n = bytes[i] >= 0 ? bytes[i] : 256 + bytes[i];              String s = Integer.toHexString(n);              if (s.length() < 2) {                  s = "0" + s;              }              if (s.length() > 2) {                  s = s.substring(s.length() - 2);              }              sb.append(s);          }          return sb.toString().toUpperCase();          //return new BASE64Encoder().encode(bytes);      }       // 一下程序将每2位16进制整数组装成一个字节      private String hexString = "0123456789ABCDEF";       public byte[] decode(String bytes) {          ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length() / 2);          for (int i = 0; i < bytes.length(); i += 2)              baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString.indexOf(bytes                  .charAt(i + 1))));          return baos.toByteArray();      }       public byte[] getKey() {          return key;      }       public void setKey(byte[] key) {          this.key = key;      }       public byte[] getIvs() {          return ivs;      }       public void setIvs(byte[] ivs) {          this.ivs = ivs;      }   }  

 

浅谈DEs,AES