zoukankan      html  css  js  c++  java
  • AES,BigInteger,MD5加密

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

    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 "";
    	}
    //

    AES算法在windows下可以正常加密、解密,上传到服务器之后,无法正常工作,每次加密的结果都是随机的

    经检查发现,是加密的密钥在Linux下随机生成造成的,  不建议使用

    	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字节

                            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG","SUN"); 建议使用该方式
    			secureRandom.setSeed(securityKey.getBytes());
    			kgen.init(secureRandom);


    			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 "";
    		}
    	}
    
    	/**
    	 *信息-摘要算法,为计算机安全领域广泛使用的一种散列函数,用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法)
    	 *1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
    	  2、容易计算:从原数据计算出MD5值很容易。
    	  3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
    	  4、强抗碰撞:已知原数据和其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;
    	}
    }
    
     
    
  • 相关阅读:
    win7同时安装python2和python3
    Centos6.8安装python3.6
    Typescript的接口
    ES5中的类相关/Typescript的类相关
    Typescript介绍
    Global Interpreter Lock 全局解释器锁
    Go语言设计模式(五)
    Go语言设计模式(四)
    Go语言反射
    Go语言程序设计(三)
  • 原文地址:https://www.cnblogs.com/xingminghui/p/7746634.html
Copyright © 2011-2022 走看看