AES,BigInteger,MD5加密

 

http://tool.oschina.net/apidocs/apidoc?api=jdk-zhjava

package cn.com.gome.cashier.web;

import java.lang.reflect.Method;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.security.Key;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.junit.Test;

import cn.com.gome.common.security.base64.Base64Util;


/**
 * javax.crypto.spec.SecretKeySpec(implements KeySpec,SecretKey)
 * java.security.spec.KeySpec, javax.crypto.SecretKey(extends java.security.Key)
 * java.security.Key
 */
public class MyTestDemo {
	private static String charset = "utf-8";

	/**
	 * HMAC(Hash Message Authentication Code,散列消息鑑別碼,基於密鑰的Hash算法的認證協議
	 */
	@Test
	public void test2(){
		String str = "12345678901234567890qwqqq";
		String encr = encrypt(str, "qazwsxedcrfvtgby");
		String encr2 = encrypt16no(str, "qazwsxedcrfvtgby");
		String encr3 = encrypt16(str, "qazwsxedcrfvtgby");
		System.out.println("加密:"+encr);
		System.out.println("加密:"+encr2);
		System.out.println("加密:"+encr3);
		String dec = decrypt(encr, "qazwsxedcrfvtgby");
		System.out.println("解密:" + dec);

	}
	//AES對稱加密 kgen.init()加不加keySize的區別 SecureRandom new與setSeed的區別
	private static String encrypt(String password, String securityKey) {
		byte[] crypted = null;
		try {
			KeyGenerator kgen = KeyGenerator.getInstance("AES");//實例化一個用AES加密算法的密鑰生成器
			SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG","SUN");
			secureRandom.setSeed(securityKey.getBytes());
			kgen.init(secureRandom);
			
			SecretKey secretKey = kgen.generateKey();
			Cipher cipher = Cipher.getInstance("AES");
			cipher.init(Cipher.ENCRYPT_MODE, secretKey);
			crypted= cipher.doFinal(password.getBytes(charset));
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		try {
			return new String(encodeBase64(crypted)).replace(" ", "");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	private static String encrypt16no(String password, String securityKey) {
		byte[] crypted = null;
		try {
			// 祕鑰位數沒限制
			KeyGenerator kgen = KeyGenerator.getInstance("AES");//實例化一個用AES加密算法的密鑰生成器
			kgen.init(128, new SecureRandom(securityKey.getBytes()));//使用用戶提供的password初始化此密鑰生成器,使其具備肯定的密鑰大小128字節長
			
			SecretKey secretKey = kgen.generateKey();//生成一個密鑰。
			byte[] enCodeFormat = secretKey.getEncoded();//返回基本編碼格式的密鑰,若是此密鑰不支持編碼,則返回 null
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");//根據給定的enCodeFormat字節數組構造一個用AES算法加密的密鑰。
			Cipher cipher = Cipher.getInstance("AES");// 建立密碼器 
			cipher.init(Cipher.ENCRYPT_MODE, key);// 能夠用 secretKey  以加密的方式用密鑰初始化此 Cipher。
			crypted = cipher.doFinal(password.getBytes("utf-8"));
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		try {
			return new String(encodeBase64(crypted)).replace(" ", "");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	private static String encrypt16(String password, String securityKey) {
		byte[] crypted = null;
		try {
			// 祕鑰必須爲16位
			 SecretKeySpec keys = new SecretKeySpec(securityKey.getBytes(),
			 "AES");
			 Cipher.getInstance("AES/ECB/PKCS5Padding");//調用靜態工廠方法獲得Cipher對象
			 Cipher cipher = Cipher.getInstance("AES");
			 cipher.init(Cipher.ENCRYPT_MODE, keys);// ENCRYPT_MODE,加密數據
			 crypted = cipher.doFinal(password.getBytes());
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		try {
			return new String(encodeBase64(crypted)).replace(" ", "");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	private static String decrypt(String input, String securityKey) {
		byte[] output = null;
		try {
			KeyGenerator kgen = KeyGenerator.getInstance("AES");
			kgen.init(128, new SecureRandom(securityKey.getBytes()));
			SecretKey secretKey = kgen.generateKey();
			byte[] enCodeFormat = secretKey.getEncoded();
			SecretKeySpec keys = new SecretKeySpec(enCodeFormat, "AES");
			Cipher cipher = Cipher.getInstance("AES");

			// SecretKeySpec keys = new SecretKeySpec(securityKey.getBytes(),
			// "AES");
			// Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

			// Cipher cipher = Cipher.getInstance("AES");

			cipher.init(Cipher.DECRYPT_MODE, secretKey);// DECRYPT_MODE,解密數據
			output = cipher.doFinal(decodeBase64(input));
		} catch (Exception e) {
			System.out.println(e.toString());
			return "";
		}
		return new String(output);
	}

	/**
	 * BigInteger位運算   對稱加解密,A、B的位運算爲C,則C、B的位運算爲A,C、A的位運算爲B
	 */
	//@Test
	public void testBigInteger(){
		String str = "asd";
		System.out.println(Arrays.toString(str.getBytes()));
		String es = encrypt(str);
		System.out.println("密文:"+es);
		System.out.println(decrypt(es));
		
		//i=15轉成二進制是1111,j=2轉成二進制是0010,根據異或的運算規則獲得的是1101,轉成十進制就是13   兩個操做數的位中,相同則結果爲0,不一樣則結果爲1  this ^ val
		BigInteger i = (new BigInteger("15")).xor( (new BigInteger("2")));
		System.out.println(i+" "+i.toString(10));//10進製表示
		i = (new BigInteger("13")).xor( (new BigInteger("2")));
		System.out.println(i+" "+i.toString(10));//10進製表示
	}
	private static final int RADIX = 16;
	private static final String SEED = "0933910847463829232312312";
	private static final String encrypt(String password) {
		BigInteger bi_passwd = new BigInteger(password.getBytes());// 將包含 BigInteger 的二進制補碼錶示形式的 byte 數組轉換爲 BigInteger
		BigInteger bi_seed = new BigInteger(SEED);
		BigInteger bi_resu = bi_seed.xor(bi_passwd);// 位運算,種子在外、密碼在內,按位運算符 異或
		System.out.println("bi_passwd: "+bi_passwd);
		System.out.println("bi_seed:"+bi_seed);
		System.out.println("bi_resu:"+bi_resu);
		return bi_resu.toString(RADIX);//返回16進製表示形式
	}
	private static final String decrypt(String encrypted) {
		BigInteger bi_confuse = new BigInteger(SEED);
		try {
			BigInteger bi_r1 = new BigInteger(encrypted, RADIX);//將16進制密文轉換爲BigInteger
			BigInteger bi_r0 = bi_r1.xor(bi_confuse);// 位運算,種子在內、密碼在外
			System.out.println("bi_r1:"+bi_r1);
			System.out.println("bi_r0:"+bi_r0);
			return new String(bi_r0.toByteArray());//將結果轉換爲字節數組,進而轉換爲字符串
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 *信息-摘要算法,爲計算機安全領域普遍使用的一種散列函數,用於確保信息傳輸完整一致。是計算機普遍使用的雜湊算法之一(又譯摘要算法、哈希算法)
	 *一、壓縮性:任意長度的數據,算出的MD5值長度都是固定的。
	  二、容易計算:從原數據計算出MD5值很容易。
	  三、抗修改性:對原數據進行任何改動,哪怕只修改1個字節,所獲得的MD5值都有很大區別。
	  四、強抗碰撞:已知原數據和其MD5值,想找到一個具備相同MD5值的數據(即僞造數據)是很是困難的。
	      遺留:SHA
	 */
	//@Test
	public void testMd5(){
		String str = "是地方薩芬撒大哥啊啊sdfasdasdfasdff34r4433333335v4ffffffffffffffffffffffffffffffff";
		try {
			String str1 = encodeMessage(str);
			System.out.println(str1);
			
			//以上代碼就能夠實現MD5摘要了。因爲摘要的結果是字節數組,並非咱們常見的字符串,因此還有工做要作。字節數組轉字符串,還不簡單
			MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] md5Bytes = messageDigest.digest(str.getBytes(Charset.forName("UTF-8")));
	        for (byte b : md5Bytes) {
	            System.out.print(b);
	        }
	        //MD5摘要的結果是一個128bit的大整數
			System.out.println(toHex2(md5Bytes));
			System.out.println(BytesConvertToHexString(md5Bytes));
			
			
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	//MD5摘要字節轉換爲字符串
	private static String toHex2(byte[] bytes) {
	    final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
	    StringBuilder ret = new StringBuilder(bytes.length * 2);
	    for (int i=0; i<bytes.length; i++) {
	        ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
	        ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
	    }
	    return ret.toString();
	}
	//MD5摘要字節轉換爲16進制字符串
	private static String BytesConvertToHexString(byte [] bytes) {
          StringBuffer sb = new StringBuffer();
          for (byte aByte : bytes) {
            String s=Integer.toHexString(0xff & aByte);
              if(s.length()==1){
                  sb.append("0"+s);
              }else{
                  sb.append(s);
              }
          }
          return sb.toString();
     }
	
	private static String encodeMessage(String data) throws Exception {
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		md5.update(data.getBytes());
		return toHex(md5.digest());
	}

	private static String toHex(byte[] buffer) {
		byte[] result = new byte[buffer.length * 2];
		for (int i = 0; i < buffer.length; i++) {
			byte[] temp = getHexValue(buffer[i]);
			result[(i * 2)] = temp[0];
			result[(i * 2 + 1)] = temp[1];
		}
		return new String(result).toUpperCase();
	}

	private static byte[] getHexValue(byte b) {
		int value = b;
		if (value < 0) {
			value = 256 + b;
		}
		String s = Integer.toHexString(value);
		if (s.length() == 1) {
			return new byte[] { 48, (byte) s.charAt(0) };
		}
		return new byte[] { (byte) s.charAt(0), (byte) s.charAt(1) };
	}
    
	/**
	 * 如下爲base64編碼   base64只能算是一個編碼算法,對數據內容進行編碼來適合傳輸
	 */
	//@Test
	public void testBase64() {
			String str = "1qazxsw23edcqwertyuiopfdgdgdfgdsgergsdfgfhrtsdf";
			String de = encode(str.getBytes());
			System.out.println(de);
			byte[] b = decode(de.getBytes());
			System.out.println(new String(b));
			
			String de2 = encodes(str.getBytes());
			System.out.println(de2);
			byte[] b2 = decodes(de2);
			System.out.println(new String(b2));
			
			
    }
	
	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;
	}

	private static String encode(final byte[] bytes) {
		return new String(Base64.encodeBase64(bytes));
	}
	private static byte[] decode(final byte[] bytes) {
		return Base64.decodeBase64(bytes);
	}

	private static String encodes(byte[] bstr) {
		return new sun.misc.BASE64Encoder().encode(bstr);
	}
	private static byte[] decodes(String str) {
		byte[] bt = null;
		try {
			sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
			bt = decoder.decodeBuffer(str);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bt;
	}
}

 
相關文章
相關標籤/搜索