AES,BigInteger,MD5加密
AES加密 字符串加密算法 Java自带的加密类MessageDigest类(加密MD5和SHA) https://blog.csdn.net/nicolezhangcheers/article/details/52038379 StringEncrypt SUN提供的常用的算法名称有:MD2 MD5 SHA-1 SHA-256 SHA-384 SHA-512 •无法通过计算找到两个散列成相同值的报文。 •摘要不反映任何与输入有关的内容。 使用报文摘要可以生成数据唯一且可靠的标识符。有时它们被称为数据的“数字指纹” public static String encryptPwd(String strSrc, String encName, String charset) throws UnsupportedEncodingException { MessageDigest md = null; String strDes = null; byte[] bt = strSrc.getBytes(charset); try { if (encName == null || encName.equals("")) { encName = "SHA-256"; } md = MessageDigest.getInstance(encName); md.update(bt); strDes = bytes2Hex(md.digest()); // to HexString } catch (NoSuchAlgorithmException e) { return null; } return strDes; } public static String bytes2Hex(byte[] bts) { String des = ""; String tmp = null; for (int i = 0; i < bts.length; i++) { tmp = (Integer.toHexString(bts[i] & 0xFF)); if (tmp.length() == 1) { des += "0"; } des += tmp; } return des; }
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; } }