java生成MD5加密
Java实现MD5加密及解密的代码实例分享
Java实现MD5加密及解密的代码实例分享基础:MessageDigest类的使⽤其实要在Java中完成MD5加密,MessageDigest类⼤部分都帮你实现好了,⼏⾏代码⾜矣:/*** 对字符串md5加密** @param str* @return*/import java.security.MessageDigest;public static String getMD5(String str) {try {// ⽣成⼀个MD5加密计算摘要MessageDigest md = MessageDigest.getInstance("MD5");// 计算md5函数md.update(str.getBytes());// digest()最后确定返回md5 hash值,返回值为8为字符串。
因为md5 hash值是16位的hex值,实际上就是8位的字符// BigInteger函数则将8位的字符串转换成16位hex值,⽤字符串来表⽰;得到字符串形式的hash值return new BigInteger(1, md.digest()).toString(16);} catch (Exception e) {throw new SpeedException("MD5加密出现错误");}}进阶:加密及解密类Java实现MD5加密以及解密类,附带测试类,具体见代码。
MD5加密解密类——MyMD5Util,代码如下package com.zyg.security.md5;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.util.Arrays;public class MyMD5Util {private static final String HEX_NUMS_STR="0123456789ABCDEF";private static final Integer SALT_LENGTH = 12;/*** 将16进制字符串转换成字节数组* @param hex* @return*/public static byte[] hexStringToByte(String hex) {int len = (hex.length() / 2);byte[] result = new byte[len];char[] hexChars = hex.toCharArray();for (int i = 0; i < len; i++) {int pos = i * 2;result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4| HEX_NUMS_STR.indexOf(hexChars[pos + 1]));}return result;}/*** 将指定byte数组转换成16进制字符串* @param b* @return*/public static String byteToHexString(byte[] b) {StringBuffer hexString = new StringBuffer();for (int i = 0; i < b.length; i++) {String hex = Integer.toHexString(b[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}hexString.append(hex.toUpperCase());}return hexString.toString();}/*** 验证⼝令是否合法* @param password* @param passwordInDb* @return* @throws NoSuchAlgorithmException* @throws UnsupportedEncodingException*/public static boolean validPassword(String password, String passwordInDb)throws NoSuchAlgorithmException, UnsupportedEncodingException {//将16进制字符串格式⼝令转换成字节数组byte[] pwdInDb = hexStringToByte(passwordInDb);//声明盐变量byte[] salt = new byte[SALT_LENGTH];//将盐从数据库中保存的⼝令字节数组中提取出来System.arraycopy(pwdInDb, 0, salt, 0, SALT_LENGTH);//创建消息摘要对象MessageDigest md = MessageDigest.getInstance("MD5");//将盐数据传⼊消息摘要对象md.update(salt);//将⼝令的数据传给消息摘要对象md.update(password.getBytes("UTF-8"));//⽣成输⼊⼝令的消息摘要byte[] digest = md.digest();//声明⼀个保存数据库中⼝令消息摘要的变量byte[] digestInDb = new byte[pwdInDb.length - SALT_LENGTH];//取得数据库中⼝令的消息摘要System.arraycopy(pwdInDb, SALT_LENGTH, digestInDb, 0, digestInDb.length); //⽐较根据输⼊⼝令⽣成的消息摘要和数据库中消息摘要是否相同if (Arrays.equals(digest, digestInDb)) {//⼝令正确返回⼝令匹配消息return true;} else {//⼝令不正确返回⼝令不匹配消息return false;}}/*** 获得加密后的16进制形式⼝令* @param password* @return* @throws NoSuchAlgorithmException* @throws UnsupportedEncodingException*/public static String getEncryptedPwd(String password)throws NoSuchAlgorithmException, UnsupportedEncodingException {//声明加密后的⼝令数组变量byte[] pwd = null;//随机数⽣成器SecureRandom random = new SecureRandom();//声明盐数组变量byte[] salt = new byte[SALT_LENGTH];//将随机数放⼊盐变量中random.nextBytes(salt);//声明消息摘要对象MessageDigest md = null;//创建消息摘要md = MessageDigest.getInstance("MD5");//将盐数据传⼊消息摘要对象md.update(salt);//将⼝令的数据传给消息摘要对象md.update(password.getBytes("UTF-8"));//获得消息摘要的字节数组byte[] digest = md.digest();//因为要在⼝令的字节数组中存放盐,所以加上盐的字节长度pwd = new byte[digest.length + SALT_LENGTH];//将盐的字节拷贝到⽣成的加密⼝令字节数组的前12个字节,以便在验证⼝令时取出盐 System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);//将消息摘要拷贝到加密⼝令字节数组从第13个字节开始的字节System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);//将字节数组格式加密后的⼝令转化为16进制字符串格式的⼝令return byteToHexString(pwd);}}测试类——Client,代码如下:package com.zyg.security.md5;import java.io.UnsupportedEncodingException;import java.security.NoSuchAlgorithmException;import java.util.HashMap;import java.util.Map;public class Client {private static Map users = new HashMap();public static void main(String[] args){String userName = "zyg";String password = "123";registerUser(userName,password);userName = "changong";password = "456";registerUser(userName,password);String loginUserId = "zyg";String pwd = "1232";try {if(loginValid(loginUserId,pwd)){System.out.println("欢迎登陆");}else{System.out.println("⼝令错误,请重新输⼊");}} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 注册⽤户** @param userName* @param password*/public static void registerUser(String userName,String password){String encryptedPwd = null;try {encryptedPwd = MyMD5Util.getEncryptedPwd(password);users.put(userName, encryptedPwd);} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 验证登陆** @param userName* @param password* @return* @throws UnsupportedEncodingException* @throws NoSuchAlgorithmException*/public static boolean loginValid(String userName,String password)throws NoSuchAlgorithmException, UnsupportedEncodingException{String pwdInDb = (String)users.get(userName);if(null!=pwdInDb){ // 该⽤户存在return MyMD5Util.validPassword(password, pwdInDb);}else{System.out.println("不存在该⽤户");return false;}}}PS:这⾥再为⼤家提供2款MD5加密⼯具,感兴趣的朋友可以参考⼀下:MD5在线加密⼯具:在线MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160加密⼯具:。
JAVA生成MD5校验码及算法实现
JAVA生成MD5校验码及算法实现在Java中,java.security.MessageDigest (rt.jar中)已经定义了MD5 的计算,所以我们只需要简单地调用即可得到MD5 的128 位整数。
然后将此128 位计16 个字节转换成16 进制表示即可。
下面是一个可生成字符串或文件MD5校验码的例子,测试过,可当做工具类直接使用,其中最主要的是getMD5String(String s)和getFileMD5String(File file)两个方法,分别用于生成字符串的md5校验值和生成文件的md5校验值,getFileMD5String_old(File file)方法可删除,不建议使用:package com.why.md5;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5Util {/*** 默认的密码字符串组合,用来将字节转换成16 进制表示的字符,apache 校验下载的文件的正确性用的就是默认的这个组合*/protected static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6','7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };protected static MessageDigest messagedigest = null;static {try {messagedigest = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException nsaex) {System.err.println(MD5Util.class.getName()+ "初始化失败,MessageDigest不支持MD5Util。
Java详解单向加密--MD5、SHA和HMAC及简单实现实例
Java详解单向加密--MD5、SHA和HMAC及简单实现实例Java 详解单向加密--MD5、SHA和HMAC及简单实现实例概要:MD5、SHA、HMAC这三种加密算法,可谓是⾮可逆加密,就是不可解密的加密⽅法。
MD5MD5即Message-Digest Algorithm 5(信息-摘要算法5),⽤于确保信息传输完整⼀致。
MD5是输⼊不定长度信息,输出固定长度128-bits的算法。
MD5算法具有以下特点:1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进⾏任何改动,哪怕只修改1个字节,所得到的MD5值都有很⼤区别。
4、强抗碰撞:已知原数据和其MD5值,想找到⼀个具有相同MD5值的数据(即伪造数据)是⾮常困难的。
MD5还⼴泛⽤于操作系统的登陆认证上,如Unix、各类BSD系统登录密码、数字签名等诸多⽅⾯。
如在Unix系统中⽤户的密码是以MD5(或其它类似的算法)经Hash运算后存储在⽂件系统中。
当⽤户登录的时候,系统把⽤户输⼊的密码进⾏MD5 Hash运算,然后再去和保存在⽂件系统中的MD5值进⾏⽐较,进⽽确定输⼊的密码是否正确。
通过这样的步骤,系统在并不知道⽤户密码的明码的情况下就可以确定⽤户登录系统的合法性。
这可以避免⽤户的密码被具有系统管理员权限的⽤户知道。
MD5将任意长度的“字节串”映射为⼀个128bit的⼤整数,并且通过该128bit反推原始字符串是⾮常困难的。
SHASHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应⽤中重要的⼯具,被⼴泛地应⽤于电⼦商务等信息安全领域。
虽然SHA与MD5通过碰撞法都被破解了,但是SHA仍然是公认的安全加密算法,较之MD5更为安全。
SHA所定义的长度下表中的中继散列值(internal state)表⽰对每个数据区块压缩散列过后的中继值(internal hash sum)。
MD5加密法
* java.security包中的MessageDigest类提供了计算消息摘要的方法,首先生成对象,执行其update( )方法可以将原始数据传递给该对象,然后执行其digest( )方法即可得到消息摘要。
*/package org.qrsx.util;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/*** MD5加密* @author Administrator**/public class DigestPass {private MessageDigest messageDigest;private String result = "";private byte[] args = null;public String getDigestPassWord(String userpass) {try {// 生成MessageDigest对象,传入所用算法的参数(MD5)messageDigest = MessageDigest.getInstance("MD5");// 使用getBytes( )方法生成字符串数组messageDigest.update(userpass.getBytes("GBK"));// 执行MessageDigest对象的digest( )方法完成计算,计算的结果通过字节类型的数组返回args = messageDigest.digest();} catch (NoSuchAlgorithmException e) {e.printStackTrace();throw new RuntimeException();} catch (UnsupportedEncodingException ee) {ee.printStackTrace();throw new RuntimeException();} finally {messageDigest.reset();}// 将结果转换成字符串result = "";// result清空,否则它会自动累加!!!for (int i = 0; i < args.length; i++) {result += Integer.toHexString((0x000000ff & args[i]) | 0xffffff00).substring(6);}return result;}。
Java和JSMD5加密-附盐值加密demo
Java和JSMD5加密-附盐值加密demo JAVA和JS的MD5加密经过测试:字母和数据好使,中⽂不好使。
源码如下:*** 类MD5Util.java的实现描述:**/public class MD5Util {// 获得MD5摘要算法的 MessageDigest 对象private static MessageDigest _mdInst = null;private static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};private static MessageDigest getMdInst() {if (_mdInst == null) {try {_mdInst = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}return _mdInst;}private MD5Util() {}/*** Returns a MessageDigest for the given <code>algorithm</code>.** @return An MD5 digest instance.* @throws RuntimeException when a {@link NoSuchAlgorithmException} is caught*/static MessageDigest getDigest() {try {return MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {throw new RuntimeException(e);}}/*** Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.** @param data Data to digest* @return MD5 digest*/public static byte[] md5(byte[] data) {return getDigest().digest(data);}/*** Calculates the MD5 digest and returns the value as a 16 element <code>byte[]</code>.** @param data Data to digest* @return MD5 digest*/public static byte[] md5(String data) {return md5(data.getBytes());}/*** Calculates the MD5 digest and returns the value as a 32 character hex string.** @param data Data to digest* @return MD5 digest as a hex string*//*public static String md5Hex(byte[] data) {return HexUtil.toHexString(md5(data));}*//*** Calculates the MD5 digest and returns the value as a 32 character hex string. ** @param data Data to digest* @return MD5 digest as a hex string*//*public static String md5Hex(String data) {return HexUtil.toHexString(md5(data));}*//*** 对密码字符串进⾏MD5加密** @param pass* @return*/public static String encoding(String pass) {if (pass == null) {return "";} else {StringBuffer buf = null;MessageDigest md5 = null;try {// 获取md5摘要md5 = MessageDigest.getInstance("MD5");// 指定utf-8编码md5.update(pass.getBytes("utf-8"));byte[] b = md5.digest();int i;buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0) {i += 256;}if (i < 16) {buf.append("0");}// 产⽣16进制保存buf.append(Integer.toHexString(i));}} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}return buf.toString();}}public final static String encode(String s) {try {byte[] btInput = s.getBytes();// 使⽤指定的字节更新摘要getMdInst().update(btInput);// 获得密⽂byte[] md = getMdInst().digest();// 把密⽂转换成⼗六进制的字符串形式int j = md.length;char str[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];str[k++] = hexDigits[byte0 >>> 4 & 0xf];str[k++] = hexDigits[byte0 & 0xf];}return new String(str);} catch (Exception e) {e.printStackTrace();return null;}}}md5.js/** A JavaScript implementation of the RSA Data Security, Inc. MD5 Message* Digest Algorithm, as defined in RFC 1321.* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet* Distributed under the BSD License* See /crypt/md5 for more info.*//** Configurable variables. You may need to tweak these to be compatible with* the server-side, but the defaults work in most cases.*/var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode *//** These are the functions you'll usually want to call* They take string arguments and return either hex or base-64 encoded strings*/function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } /** Perform a simple self-test to see if the VM is working*/function md5_vm_test(){return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";}/** Calculate the MD5 of an array of little-endian words, and a bit length*/function core_md5(x, len){/* append padding */x[len >> 5] |= 0x80 << ((len) % 32);x[(((len + 64) >>> 9) << 4) + 14] = len;var a = 1732584193;var b = -271733879;var c = -1732584194;var d = 271733878;for(var i = 0; i < x.length; i += 16){var olda = a;var oldb = b;var oldc = c;var oldd = d;a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);c = md5_ff(c, d, a, b, x[i+10], 17, -42063);b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);a = safe_add(a, olda);b = safe_add(b, oldb);c = safe_add(c, oldc);d = safe_add(d, oldd);}return Array(a, b, c, d);}/** These functions implement the four basic operations the algorithm uses. */function md5_cmn(q, a, b, x, s, t){return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);}function md5_ff(a, b, c, d, x, s, t){return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);}function md5_gg(a, b, c, d, x, s, t){return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);}function md5_hh(a, b, c, d, x, s, t){return md5_cmn(b ^ c ^ d, a, b, x, s, t);}function md5_ii(a, b, c, d, x, s, t){return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);}/** Calculate the HMAC-MD5, of a key and some data*/function core_hmac_md5(key, data){var bkey = str2binl(key);if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);var ipad = Array(16), opad = Array(16);for(var i = 0; i < 16; i++){ipad[i] = bkey[i] ^ 0x36363636;opad[i] = bkey[i] ^ 0x5C5C5C5C;}var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);return core_md5(opad.concat(hash), 512 + 128);}/** Add integers, wrapping at 2^32. This uses 16-bit operations internally* to work around bugs in some JS interpreters.*/function safe_add(x, y){var lsw = (x & 0xFFFF) + (y & 0xFFFF);var msw = (x >> 16) + (y >> 16) + (lsw >> 16);return (msw << 16) | (lsw & 0xFFFF);}/** Bitwise rotate a 32-bit number to the left.*/function bit_rol(num, cnt){return (num << cnt) | (num >>> (32 - cnt));}/** Convert a string to an array of little-endian words* If chrsz is ASCII, characters >255 have their hi-byte silently ignored.*/function str2binl(str){var bin = Array();var mask = (1 << chrsz) - 1;for(var i = 0; i < str.length * chrsz; i += chrsz)bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);return bin;}/** Convert an array of little-endian words to a string*/function binl2str(bin){var str = "";var mask = (1 << chrsz) - 1;for(var i = 0; i < bin.length * 32; i += chrsz)str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);return str;}/** Convert an array of little-endian words to a hex string.*/function binl2hex(binarray){var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";var str = "";for(var i = 0; i < binarray.length * 4; i++){str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);}return str;}/** Convert an array of little-endian words to a base-64 string*/function binl2b64(binarray){var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var str = "";for(var i = 0; i < binarray.length * 4; i += 3){var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)| (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )| ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);for(var j = 0; j < 4; j++){if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);}}return str;}测试DEMO类(⼯具类加密后转成⼩写):public class Test {public static void main(String[] args) throws Exception {String source = "123AB";String salt = "asdklsakjfdlsadjfl";System.out.printf("source is %s,result is %s",salt+source,MD5Util.encode(salt+source).toLowerCase()); }}运⾏结果:source is asdklsakjfdlsadjfl123AB,result is d5976dad58ad32000e3867f0601e236c。
JAVA中获取文件MD5值的四种方法
JAVA中获取⽂件MD5值的四种⽅法 JAVA中获取⽂件MD5值的四种⽅法其实都很类似,因为核⼼都是通过JAVA⾃带的MessageDigest类来实现。
获取⽂件MD5值主要分为三个步骤,第⼀步获取⽂件的byte信息,第⼆步通过MessageDigest类进⾏MD5加密,第三步转换成16进制的MD5码值。
⼏种⽅法的不同点主要在第⼀步和第三步上。
具体可以看下⾯的例⼦:⽅法⼀、1 private final static String[] strHex = { "0", "1", "2", "3", "4", "5",2 "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };34 public static String getMD5One(String path) {5 StringBuffer sb = new StringBuffer();6 try {7 MessageDigest md = MessageDigest.getInstance("MD5");8 byte[] b = md.digest(FileUtils.readFileToByteArray(new File(path)));9 for (int i = 0; i < b.length; i++) {10 int d = b[i];11 if (d < 0) {12 d += 256;13 }14 int d1 = d / 16;15 int d2 = d % 16;16 sb.append(strHex[d1] + strHex[d2]);17 }18 } catch (NoSuchAlgorithmException e) {19 e.printStackTrace();20 } catch (IOException e) {21 e.printStackTrace();22 }23 return sb.toString();24 } ⽅法⼀是⽐较原始的⼀种实现⽅法,⾸先将⽂件⼀次性读⼊内存,然后通过MessageDigest进⾏MD5加密,最后再⼿动将其转换为16进制的MD5值。
MD5的使用方法
MD5的使⽤⽅法MD5加密的Java实现在各种应⽤系统中,如果需要设置账户,那么就会涉及到存储⽤户账户信息的问题,为了保证所存储账户信息的安全,通常会采⽤MD5加密的⽅式来,进⾏存储。
⾸先,简单得介绍⼀下,什么是MD5加密。
MD5的全称是Message-Digest Algorithm 5 (信息-摘要算法),在90年代初,由MIT Laboratory for Computer Scientce 和RSA Data Security Inc 的 Ronald L.Rivest开发出来,经MD2、MD3和MD4发展⽽来。
是让⼤容量信息在⽤数字签名软件签署私⼈密匙前被"压缩"成⼀种保密的格式(就是把⼀个任意长度的字节串变换成⼀定长的⼤整数)。
不管是MD2、MD4还是MD5,它们都需要获得⼀个随机长度的信息并产⽣⼀个128位的信息摘要。
虽然这些算法的结构或多或少有些相似,但MD2的设计与MD4和MD5完全不同,那是因为MD2是为8位机器做过设计优化的,⽽MD4和MD5却是⾯向32位的电脑。
这三个算法的描述和C语⾔源代码在Internet RFCs 1321中有详细的描述,这是⼀份最权威的⽂档,由Ronald L.Rivest在1992年8⽉向IETF提交。
(⼀)消息摘要简介⼀个消息摘要就是⼀个数据块的数字指纹。
即对⼀个任意长度的⼀个数据块进⾏计算,产⽣⼀个唯⼀指印(对于SHA1是产⽣⼀个20字节的⼆进制数组)。
消息摘要是⼀种与消息认证码结合使⽤以确保消息完整性的技术。
主要使⽤单向散列函数算法,可⽤于检验消息的完整性,和通过散列密码直接以⽂本形式保存等,⽬前⼴泛使⽤的算法由MD4、MD5、SHA-1.消息摘要有两个基本属性:1.两个不同的报⽂难以⽣成相同的摘要2.难以对指定的摘要⽣成⼀个报⽂,⽽可以由改报⽂反推算出该指定的摘要代表:美国国家标准技术研究所的SHA1和⿇省理⼯学院Ronald Rivest提出的MD5(⼆)对字符串进⾏加密package test;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import sun.misc.BASE64Encoder;/*** 对字符串进⾏加密* @param str 待加密的字符串* @return 加密后的字符串* @throws NoSuchAlgorithmException 没有这种产⽣消息摘要的算法* @throws UnsupportedEncodingException*/public class Demo01 {public static String EncoderByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException{//确定算法MessageDigest md5 = MessageDigest.getInstance("MD5");BASE64Encoder base64en = new BASE64Encoder();//加密后的字符串String newstr = base64en.encode(md5.digest(str.getBytes("utf-8")));return newstr;}public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {String str = "0123456789";System.out.println(EncoderByMd5(str));}}(三)验证密码是否正确package test;import java.io.UnsupportedEncodingException;import java.security.NoSuchAlgorithmException;/*** 判断⽤户密码是否正确* @param newpasswd ⽤户输⼊的密码* @param oldpasswd 数据库中存储的密码--⽤户密码的摘要* @return* @throws NoSuchAlgorithmException* @throws UnsupportedEncodingException**/public class Demo02 {public static boolean checkpassword(String newpasswd, String oldpasswd) throws NoSuchAlgorithmException, UnsupportedEncodingException{if (Demo01.EncoderByMd5(newpasswd).equals(oldpasswd)) {return true;} else {return false;}}public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {System.out.println("old:"+Demo01.EncoderByMd5("123"));System.out.println("new:"+Demo01.EncoderByMd5("123"));System.out.println(checkpassword("123",Demo01.EncoderByMd5("123")));}}因为MD5是基于消息摘要原理的,消息摘要的基本特征就是很难根据摘要推算出消息报⽂,因此要验证密码是否正确,就必须对输⼊密码(消息报⽂)重新计算其摘要,和数据库中存储的摘要进⾏对⽐(即数据库中存储的其实为⽤户密码的摘要),若两个摘要相同,则说明密码正确,不同,则说明密码错误。
java加密解密算法MD5SHA1,DSA
java加密解密算法MD5SHA1,DSA通常,使⽤的加密算法⽐较简便⾼效,密钥简短,加解密速度快,破译极其困难。
本⽂介绍了MD5/SHA1,DSA,DESede/DES,Diffie-Hellman的使⽤。
第1章基础知识1.1. 单钥密码体制单钥密码体制是⼀种传统的加密,是指信息的发送⽅和接收⽅共同使⽤同⼀把密钥进⾏加解密。
通常,使⽤的加密算法⽐较简便⾼效,密钥简短,加解密速度快,破译极其困难。
但是加密的安全性依靠密钥保管的安全性,在公开的上安全地传送和保管密钥是⼀个严峻的问题,并且如果在多⽤户的情况下密钥的保管安全性也是⼀个问题。
单钥密码体制的代表是美国的DES1.2. 消息摘要⼀个消息摘要就是⼀个数据块的数字指纹。
即对⼀个任意长度的⼀个数据块进⾏计算,产⽣⼀个唯⼀指印(对于SHA1是产⽣⼀个20字节的⼆进制数组)。
消息摘要有两个基本属性:两个不同的报⽂难以⽣成相同的摘要难以对指定的摘要⽣成⼀个报⽂,⽽由该报⽂反推算出该指定的摘要代表:美国国家标准技术研究所的SHA1和⿇省理⼯学院Ronald Rivest提出的MD51.3. Diffie-Hellman密钥⼀致协议密钥⼀致协议是由公开密钥密码体制的奠基⼈Diffie和Hellman所提出的⼀种思想。
先决条件,允许两名⽤户在公开媒体上交换信息以⽣成"⼀致"的,可以共享的密钥代表:指数密钥⼀致协议(Exponential Key Agreement Protocol)1.4. ⾮对称算法与公钥体系1976 年,Dittie和Hellman为解决密钥管理问题,在他们的奠基性的⼯作"密码学的新⽅向"⼀⽂中,提出⼀种密钥交换协议,允许在不安全的媒体上通过通讯双⽅交换信息,安全地传送秘密密钥。
在此新思想的基础上,很快出现了⾮对称密钥密码体制,即公钥密码体制。
在公钥体制中,加密密钥不同于解密密钥,加密密钥公之于众,谁都可以使⽤;解密密钥只有解密⼈⾃⼰知道。
java中使用MD5进行计算摘要
java中使⽤MD5进⾏计算摘要java中使⽤MD5进⾏加密在各种应⽤系统的开发中,经常需要存储⽤户信息,很多地⽅都要存储⽤户密码,⽽将⽤户密码直接存储在服务器上显然是不安全的,本⽂简要介绍⼯作中常⽤的 MD5加密算法,希望能抛砖引⽟。
(⼀)消息摘要简介⼀个消息摘要就是⼀个数据块的数字指纹。
即对⼀个任意长度的⼀个数据块进⾏计算,产⽣⼀个唯⼀指印(对于SHA1是产⽣⼀个20字节的⼆进制数组)。
消息摘要是⼀种与消息认证码结合使⽤以确保消息完整性的技术。
主要使⽤单向散列函数算法,可⽤于检验消息的完整性,和通过散列密码直接以⽂本形式保存等,⽬前⼴泛使⽤的算法有MD4、MD5、SHA-1。
消息摘要有两个基本属性:1. 两个不同的报⽂难以⽣成相同的摘要2. 难以对指定的摘要⽣成⼀个报⽂,⽽可以由该报⽂反推算出该指定的摘要代表:美国国家标准技术研究所的SHA1和⿇省理⼯学院Ronald Rivest提出的MD5(⼆)对字符串进⾏加密/**利⽤MD5进⾏加密* @param str 待加密的字符串* @return加密后的字符串* @throws NoSuchAlgorithmException 没有这种产⽣消息摘要的算法* @throws UnsupportedEncodingException*/public String EncoderByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException{//确定计算⽅法MessageDigest md5=MessageDigest.getInstance("MD5");BASE64Encoder base64en = new BASE64Encoder();//加密后的字符串String newstr=base64en.encode(md5.digest(str.getBytes("utf-8")));return newstr;}调⽤函数:String str="0123456789"System.out.println(EncoderByMd5(str));输出:eB5eJF1ptWaXm4bijSPyxw==(三)验证密码是否正确因为MD5是基于消息摘要原理的,消息摘要的基本特征就是很难根据摘要推算出消息报⽂,因此要验证密码是否正确,就必须对输⼊密码(消息报⽂)重新计算其摘要,和数据库中存储的摘要进⾏对⽐(即数据库中存储的其实为⽤户密码的摘要),若两个摘要相同,则说明密码正确,不同,则说明密码错误。
java传输json数据用md5加密过程
("encrypted: " + md5Encrypted); if(!md5Encrypted.equalsIgnoreCase(param.getSign())){
try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update( content.getBytes() ); return getHashString( md ); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
JSONObject inputJson=JSONObject.parseObject(lines); reader.close();
System.out.println(md5Encrypt(encrapted)); return inputJson; } public String md5Encrypt(String content) {
//input BufferedReader reader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream())); String lines =reader.readLine();//��ȡ������
}else{ this.response(response, JSONObject.toJSONString(new ResultObject(ResultCode.NULL_PARAM)));
Java 加密解密之消息摘要算法(MD5 SHA MAC)
Java 加密解密之消息摘要算法(MD5 SHA MAC)本文转自网络消息摘要消息摘要(Message Digest)又称为数字摘要(Digital Digest)。
它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。
如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了。
因此消息摘要保证了消息的完整性。
消息摘要采用单向Hash 函数将需加密的明文"摘要"成一串128bit的密文,这一串密文亦称为数字指纹(Finger Print),它有固定的长度,且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。
这样这串摘要便可成为验证明文是否是"真身"的"指纹"了。
HASH函数的抗冲突性使得如果一段明文稍有变化,哪怕只更改该段落的一个字母,通过哈希算法作用后都将产生不同的值。
而HASH算法的单向性使得要找到到哈希值相同的两个不同的输入消息,在计算上是不可能的。
所以数据的哈希值,即消息摘要,可以检验数据的完整性。
哈希函数的这种对不同的输入能够生成不同的值的特性使得无法找到两个具有相同哈希值的输入。
因此,如果两个文档经哈希转换后成为相同的值,就可以肯定它们是同一文档。
所以,当希望有效地比较两个数据块时,就可以比较它们的哈希值。
例如,可以通过比较邮件发送前和发送后的哈希值来验证该邮件在传递时是否修改。
消息摘要算法消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密,只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文。
消息摘要算法不存在密钥的管理与分发问题,适合于分布式网络相同上使用。
由于其加密计算的工作量相当可观,所以以前的这种算法通常只用于数据量有限的情况下的加密,例如计算机的口令就是用不可逆加密算法加密的。
近年来,随着计算机相同性能的飞速改善,加密速度不再成为限制这种加密技术发展的桎梏,因而消息摘要算法应用的领域不断增加。
MD5加盐Java加密算法
MD5加盐Java加密算法import java.security.MessageDigest;public class PasswordEncoder {private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };private Object salt;private String algorithm;public PasswordEncoder(Object salt, String algorithm) {this.salt = salt;this.algorithm = algorithm;}public String encode(String rawPass) {String result = null;try {MessageDigest md = MessageDigest.getInstance(algorithm);//加密后的字符串result = byteArrayToHexString(md.digest(mergePasswordAndSalt(rawPass).getBytes("utf-8")));} catch (Exception ex) {}return result;}public boolean isPasswordValid(String encPass, String rawPass) {String pass1 = "" + encPass;String pass2 = encode(rawPass);return pass1.equals(pass2);}private String mergePasswordAndSalt(String password) {if (password == null) {password = "";}if ((salt == null) || "".equals(salt)) {return password;} else {return password + "{" + salt.toString() + "}";}}/*** 转换字节数组为16进制字串* @param b 字节数组* @return 16进制字串*/private static String byteArrayToHexString(byte[] b) {StringBuffer resultSb = new StringBuffer();for (int i = 0; i < b.length; i++) {resultSb.append(byteToHexString(b[i]));}return resultSb.toString();}private static String byteToHexString(byte b) {int n = b;if (n < 0)n = 256 + n;int d1 = n / 16;int d2 = n % 16;return hexDigits[d1] + hexDigits[d2];}public static void main(String[] args) {String salt = "helloworld";PasswordEncoder encoderMd5 = new PasswordEncoder(salt, "MD5");String encode = encoderMd5.encode("test");System.out.println(encode);boolean passwordValid = encoderMd5.isPasswordValid("1bd98ed329aebc7b2f89424b5a38926e", "test"); System.out.println(passwordValid);PasswordEncoder encoderSha = new PasswordEncoder(salt, "SHA");String pass2 = encoderSha.encode("test");System.out.println(pass2);boolean passwordValid2 = encoderSha.isPasswordValid("1bd98ed329aebc7b2f89424b5a38926e", "test"); System.out.println(passwordValid2);}}。
使用JAVA生成MD5编码
使⽤JAVA⽣成MD5编码MD5即Message-Digest Algorithm 5(信息-摘要算法5),是⼀种⽤于产⽣数字签名的单项散列算法,在1991年由MIT Laboratory for Computer Science(IT计算机科学实验室)和RSA Data Security Inc(RSA数据安全公司)的Ronald L. Rivest教授开发出来,经由MD2、MD3和MD4发展⽽来。
MD5算法的使⽤不需要⽀付任何版权费⽤。
它的作⽤是让⼤容量信息在⽤数字签名软件签私⼈密匙前被"压缩"成⼀种保密的格式(将⼀个任意长度的“字节串”通过⼀个不可逆的字符串变换算法变换成⼀个128bit的⼤整数,换句话说就是,即使你看到源程序和算法描述,也⽆法将⼀个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有⽆穷多个,这有点象不存在反函数的数学函数。
)在 Java 中,java.security.MessageDigest 中已经定义了 MD5 的计算,所以我们只需要简单地调⽤即可得到 MD5 的128 位整数。
然后将此 128 位计 16 个字节转换成 16 进制表⽰即可。
代码如下:/**** <p>* Created on 2011-11-25* </p>*/package com.util;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/*** 功能:MD5加密算法* 公司名称:夏影* 修改时间:2011-11-15*/public class Md5Encrypt {/*** Used building output as Hex*/private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6','7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };/*** 对字符串进⾏MD5加密** @param text* 明⽂** @return密⽂*/public static String md5(String text) {MessageDigest msgDigest = null;try {msgDigest = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {throw new IllegalStateException("System doesn't support MD5 algorithm.");}try {msgDigest.update(text.getBytes("GBK")); //这个加密算法是按照GBK编码进⾏加密} catch (UnsupportedEncodingException e) {throw new IllegalStateException("System doesn't support your EncodingException.");}byte[] bytes = msgDigest.digest();String md5Str = new String(encodeHex(bytes));return md5Str;}public static char[] encodeHex(byte[] data) {int l = data.length;char[] out = new char[l << 1];// two characters form the hex value.for (int i = 0, j = 0; i < l; i++) {out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];out[j++] = DIGITS[0x0F & data[i]];}return out;}}测试代码如下:package com.util;public class TestMD5 {public static void main(String[] args) {// 计算 "a" 的 MD5 代码,应该为:0cc175b9c0f1b6a831c399e269772661System.out.println(Md5Encrypt.md5("a"));}}MD5的典型应⽤是对⼀段Message(字节串)产⽣fingerprint(指纹),以防⽌被"篡改"。
Java常见摘要算法——md5、sha1、sha256
Java常见摘要算法——md5、sha1、sha256⽬录实现sha256的代码和sha1的代码相似摘要算法简介 摘要算法,也是加密算法的⼀种,还有另外⼀种叫法:指纹。
摘要算法就是对指定的数据进⾏⼀系列的计算,然后得出⼀个串内容,该内容就是该数据的摘要。
不同的数据产⽣的摘要是不同的,所以,可以⽤它来进⾏⼀些数据加密的⼯作:通过对⽐两个数据加密后的摘要是否相同,来判断这两个数据是否相同。
还可以⽤来保证数据的完整性,常见的软件在发布之后,会同时发布软件的md5和sha值,这个md5和sha值就是软件的摘要。
当⽤户将软件下载之后,然后去计算软件的摘要,如果计算所得的摘要和软件发布⽅提供的摘要相同,则证明下载的软件和发布的软件⼀模⼀样,否则,就是下载过程中数据(软件)被篡改了。
常见的摘要算法包括:md、sha这两类。
md包括md2、md4、md5;sha包括sha1、sha224、sha256、sha384、sha512。
md5 md摘要算法包括多种算法:分别是md2、md4、md5。
现在⼀般都是使⽤md5进⾏加密。
Java中实现md5加密,有三种⽅式: 使⽤jdk内置的⽅法实现实现md5加密package cn.ganlixin.security;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import mons.codec.binary.Hex;public class JdkMD5 {public static void main(String[] args) throws NoSuchAlgorithmException {String plainText = "this is plain text";// 通过调⽤MessageDigest(数据摘要类)的getInstance()静态⽅法,传⼊加密算法的名称,获取数据摘要对象。
java MD5加密工具类
package com.person.util;import ng.reflect.Array;public class MD5 {/* 下面这些S11-S44实际上是\uFFFD \uFFFD4*4的矩阵,在原始的C实现中是\uFFFD#define 现的,这里把它们实现成为static final是表示了只读,切能在同一个进程空间内的多\uFFFD Instance 共\uFFFD*/static final int S11 = 7;static final int S12 = 12;static final int S13 = 17;static final int S14 = 22;static final int S21 = 5;static final int S22 = 9;static final int S23 = 14;static final int S24 = 20;static final int S31 = 4;static final int S32 = 11;static final int S33 = 16;static final int S34 = 23;static final int S41 = 6;static final int S42 = 10;static final int S43 = 15;static final int S44 = 21;static final byte[] PADDING = {-128, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};/* 面的三个成员是MD5计算过程中用到的3个核心数据,在原始的C实现\uFFFD 定义到MD5_CTX结构\uFFFD*/private long[] state = new long[4]; // state (ABCD)private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb first)private byte[] buffer = new byte[64]; // input buffer/* digestHexStr MD5的唯\uFFFD \uFFFD个公共成员,是最新一次计算结果的\uFFFD 16 制ASCII表示.*/public String digestHexStr;/* digest,是最新一次计算结果的2进制内部表示,表\uFFFD128bit MD5\uFFFD.*/private byte[] digest = new byte[16];/*getMD5ofStr 类MD5\uFFFD 要的公共方法,入口参数是你想要进行MD5变换的字符串返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的.*/public String getMD5ofStr(String inbuf) {md5Init();md5Update(inbuf.getBytes(), inbuf.length());md5Final();digestHexStr = "";for (int i = 0; i < 16; i++) {digestHexStr += byteHEX(digest[i]);}return digestHexStr;}// 这是MD5这个类的标准构\uFFFD 数,JavaBean要求有一个public的并且没有参数的构\uFFFD \uFFFDpublic MD5() {md5Init();return;}/* md5Init 一个初始化函数,初始化核心变量,装入标准的幻数*/private void md5Init() {count[0] = 0L;count[1] = 0L;///* Load magic initialization constants.state[0] = 0x67452301L;state[1] = 0xefcdab89L;state[2] = 0x98badcfeL;state[3] = 0x10325476L;return;/* F, G, H ,I \uFFFD4 基本的MD5函数,在原始的MD5的C实现中,由于它们\uFFFD \uFFFD单的位运算,可能出于效率的\uFFFD 把它们实现成了宏,在java中,我们把它\uFFFD\uFFFD\uFFFD 现成了private方法,名字保持了原来C中的\uFFFD */private long F(long x, long y, long z) {return (x & y) | ((~x) & z);}private long G(long x, long y, long z) {return (x & z) | (y & (~z));}private long H(long x, long y, long z) {return x ^ y ^ z;}private long I(long x, long y, long z) {return y ^ (x | (~z));}/*FF,GG,HH II将调用F,G,H,I进行近一步变\uFFFDFF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.Rotation is separate from addition to prevent recomputation.*/private long FF(long a, long b, long c, long d, long x, long s,long ac) {a += F(b, c, d) + x + ac;a = ((int) a << s) | ((int) a >>> (32 - s));a += b;return a;}private long GG(long a, long b, long c, long d, long x, long s,long ac) {a += G(b, c, d) + x + ac;a = ((int) a << s) | ((int) a >>> (32 - s));a += b;return a;private long HH(long a, long b, long c, long d, long x, long s,long ac) {a += H(b, c, d) + x + ac;a = ((int) a << s) | ((int) a >>> (32 - s));a += b;return a;}private long II(long a, long b, long c, long d, long x, long s,long ac) {a += I(b, c, d) + x + ac;a = ((int) a << s) | ((int) a >>> (32 - s));a += b;return a;}/*md5Update MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成private\uFFFD */private void md5Update(byte[] inbuf, int inputLen) {int i, index, partLen;byte[] block = new byte[64];index = (int) (count[0] >>> 3) & 0x3F;// /* Update number of bits */if ((count[0] += (inputLen << 3)) < (inputLen << 3))count[1]++;count[1] += (inputLen >>> 29);partLen = 64 - index;// Transform as many times as possible.if (inputLen >= partLen) {md5Memcpy(buffer, inbuf, index, 0, partLen);md5Transform(buffer);for (i = partLen; i + 63 < inputLen; i += 64) {md5Memcpy(block, inbuf, 0, i, 64);md5Transform(block);}index = 0;} elsei = 0;///* Buffer remaining input */md5Memcpy(buffer, inbuf, index, i, inputLen - i);}/*md5Final 理和填写输出结\uFFFD*/private void md5Final() {byte[] bits = new byte[8];int index, padLen;///* Save number of bits */Encode(bits, count, 8);///* Pad out to 56 mod 64.index = (int) (count[0] >>> 3) & 0x3f;padLen = (index < 56) ? (56 - index) : (120 - index);md5Update(PADDING, padLen);///* Append length (before padding) */md5Update(bits, 8);///* Store state in digest */Encode(digest, state, 16);}/* md5Memcpy 一个内部使用的byte数组的块拷贝函数,从input的inpos\uFFFD 把len 长度\uFFFD\uFFFD\uFFFD \uFFFD\uFFFD \uFFFD 字节拷贝到output的outpos位置\uFFFD \uFFFD */private void md5Memcpy(byte[] output, byte[] input,int outpos, int inpos, int len) {int i;for (i = 0; i < len; i++)output[outpos + i] = input[inpos + i];}/*md5Transform是MD5核心变换程序,有md5Update调用,block是分块的原始字节*/private void md5Transform(byte block[]) {long a = state[0], b = state[1], c = state[2], d = state[3];long[] x = new long[16];Decode(x, block, 64);/* Round 1 */a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 *//* Round 2 */a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */ c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */ b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 *//* Round 3 */a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */ d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */ c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */ a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */ d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */ b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */ a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */ c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */ b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */ a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */ d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */ c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */ b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 *//* Round 4 */a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */ b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */ d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */ c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */ a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */ c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */state[0] += a;state[1] += b;state[2] += c;state[3] += d;}/*Encode把long数组按顺序拆成byte数组,因为java的long类型\uFFFD64bit ,只拆\uFFFD32bit 以适应原始C实现的用\uFFFD*/private void Encode(byte[] output, long[] input, int len) {int i, j;for (i = 0, j = 0; j < len; i++, j += 4) {output[j] = (byte) (input[i] & 0xffL);output[j + 1] = (byte) ((input[i] >>> 8) & 0xffL);output[j + 2] = (byte) ((input[i] >>> 16) & 0xffL);output[j + 3] = (byte) ((input[i] >>> 24) & 0xffL);}}/*Decode byte数组按顺序合成成long数组,因为java的long类型\uFFFD64bit ,只合成低32bit,高32bit清零,以适应原始C实现的用\uFFFD*/private void Decode(long[] output, byte[] input, int len) {int i, j;for (i = 0, j = 0; j < len; i++, j += 4)output[i] = b2iu(input[j]) |(b2iu(input[j + 1]) << 8) |(b2iu(input[j + 2]) << 16) |(b2iu(input[j + 3]) << 24);return;}/*b2iu 我写的\uFFFD 把byte按照不\uFFFD 正负号的原则的"升位"程序,因为java 没有unsigned运算*/public static long b2iu(byte b) {return b < 0 ? b & 0x7F + 128 : b;}/*byteHEX(),用来把\uFFFD byte类型的数转换成十六进制的ASCII表示\uFFFD\uFFFD因为java中的byte的toString无法实现这一点,我们又没有C语言中的sprintf(outbuf,"%02X",ib)*/public static String byteHEX(byte ib) {char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','A', 'B', 'C', 'D', 'E', 'F'};char [] ob = new char[2];ob[0] = Digit[(ib >>> 4) & 0X0F];ob[1] = Digit[ib & 0X0F];String s = new String(ob);return s;}public static void main(String args[]) {MD5 m = new MD5();if (Array.getLength(args) == 0) { //如果没有参数,执行标准的Test SuiteSystem.out.println("MD5 Test suite:");System.out.println("MD5(\"\"):" + m.getMD5ofStr(""));System.out.println("MD5(\"a\"):" + m.getMD5ofStr("a"));System.out.println("MD5(\"abc\"):" + m.getMD5ofStr("abc"));System.out.println("MD5(\"message digest\"):" + m.getMD5ofStr("message digest"));System.out.println("MD5(\"abcdefghijklmnopqrstuvwxyz\"):" +m.getMD5ofStr("abcdefghijklmnopqrstuvwxyz"));System.out.println("MD5(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw xyz0123456789\"):" +m.getMD5ofStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345 6789"));} elseSystem.out.println("MD5(" + args[0] + ")=" + m.getMD5ofStr(args[0]));}}。
Java的MD5盐值加密,Des加密解密和base64加密解密使用方法
Java的MD5盐值加密,Des加密解密和base64加密解密使⽤⽅法java⽀持md5盐值加密和des加密。
做项⽬时,某些模块添加加密功能可以提⾼⽤户个⼈信息安全性,防⽌信息泄露,其中des⽀持加密解密,MD5⽬前只⽀持加密(多⽤于⽤户登录密码验证,所以⽆需解密展⽰)。
⼀、MD5盐值加密1.在pom⽂件中导⼊相关jar包<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.3.2</version></dependency>2.编写MD5类import org.apache.shiro.crypto.hash.SimpleHash;/*** 加密⼯具类* @author john**/public class MD5 {//加密类型private static String hashName="MD5";//加密次数private static int hashNum=1024;//pwd是需要加密的字符,salt是盐值(⾃定义),hashNum是加密次数,次数越多越安全public static Object getMD5(String pwd,String salt){Object obj=new SimpleHash(hashName, pwd, salt, hashNum);return obj;}}加密⽅法是静态⽅法,使⽤时直接MD5.getMD5(pwd,salt).toString();即可。
暂⽆解密⽅法。
⼆、Base64加密1.同样第⼀步也是导⼊base相关jar包<!-- Base64 --><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.14</version></dependency>2.编写base64类import mons.codec.binary.Base64;public class Base64Utils {/*** 加密** @param plainText* @return*/public static String encodeStr(String plainText) {byte[] b = plainText.getBytes();Base64 base64 = new Base64();b = base64.encode(b);return new String(b);}/*** 解密** @param encodeStr* @return*/public static String decodeStr(String encodeStr) {byte[] b = encodeStr.getBytes();Base64 base64 = new Base64();b = base64.decode(b);return new String(b);}}加密解密的⽅法同样是静态⽅法,直接类名.⽅法名调⽤即可。
md5加密,md5加盐加密和解密
md5加密,md5加盐加密和解密package com.java.test;import java.security.MessageDigest;import java.security.SecureRandom;import java.util.Arrays;public class Test {private static final Integer SALT_LENGTH = 12;/*** 16进制数字*/private static final String HEX_NUMS_STR="0123456789abcdef";/*----------------md5普通加密*//**** MD5加密⽣成32位md5码* @param待加密字符串* @return返回32位md5码*/public static String md5Encode(String inStr) throws Exception {MessageDigest md5 = null;try {md5 = MessageDigest.getInstance("MD5");} catch (Exception e) {System.out.println(e.toString());e.printStackTrace();return "";}byte[] byteArray = inStr.getBytes("UTF-8");byte[] md5Bytes = md5.digest(byteArray);StringBuffer hexValue = new StringBuffer();for (int i = 0; i < md5Bytes.length; i++) {int val = ((int) md5Bytes[i]) & 0xff;if (val < 16) {hexValue.append("0");}hexValue.append(Integer.toHexString(val));}return hexValue.toString();}/*----------------md5加盐加密和解密*//*** 获得加密后的16进制形式⼝令* @param password* @return* @throws Exception* @throws NoSuchAlgorithmException* @throws UnsupportedEncodingException*/public static String getEncryptedPwd(String password) throws Exception{try{//声明加密后的⼝令数组变量byte[] pwd = null;//随机数⽣成器SecureRandom random = new SecureRandom();//声明盐数组变量byte[] salt = new byte[SALT_LENGTH];//将随机数放⼊盐变量中random.nextBytes(salt);//获得加密的数据byte[] digest = encrypte(salt,password);//因为要在⼝令的字节数组中存放盐,所以加上盐的字节长度pwd = new byte[digest.length + SALT_LENGTH];//将盐的字节拷贝到⽣成的加密⼝令字节数组的前12个字节,以便在验证⼝令时取出盐System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);//将消息摘要拷贝到加密⼝令字节数组从第13个字节开始的字节System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);//将字节数组格式加密后的⼝令转化为16进制字符串格式的⼝令return byteToHexString(pwd);}catch(Exception e){throw new Exception("获取加密密码失败",e);}}/**** 根据盐⽣成密码* @param salt* @param passwrod* @return* @throws Exception* @throws UnsupportedEncodingException* @throws NoSuchAlgorithmException*/public static byte[] encrypte(byte[] salt,String passwrod) throws Exception{try{//声明消息摘要对象MessageDigest md = null;//创建消息摘要md = MessageDigest.getInstance("MD5");//将盐数据传⼊消息摘要对象md.update(salt);//将⼝令的数据传给消息摘要对象md.update(passwrod.getBytes("UTF-8"));//获得消息摘要的字节数组return md.digest();}catch(Exception e){throw new Exception("Md5解密失败",e);}}/*** 将指定byte数组转换成16进制字符串(⼤写)* @param b* @return*/public static String byteToHexString(byte[] bytes) {StringBuffer md5str = new StringBuffer();//把数组每⼀字节换成16进制连成md5字符串int digital;for (int i = 0; i < bytes.length; i++) {digital = bytes[i];if(digital < 0) {digital += 256;}if(digital < 16){md5str.append("0");}md5str.append(Integer.toHexString(digital));}return md5str.toString();}/*** 验证⼝令是否合法* @param password* @param passwordInDb* @return* @throws Exception* @throws NoSuchAlgorithmException* @throws UnsupportedEncodingException*/public static boolean validPassword(String password, String passwordInDb) throws Exception { try{//将16进制字符串格式⼝令转换成字节数组byte[] pwdInDb = hexStringToByte(passwordInDb);//声明盐变量byte[] salt = new byte[SALT_LENGTH];//将盐从数据库中保存的⼝令字节数组中提取出来System.arraycopy(pwdInDb, 0, salt, 0, SALT_LENGTH);//获得加密的数据byte[] digest = encrypte(salt,password);//声明⼀个保存数据库中⼝令消息摘要的变量byte[] digestInDb = new byte[pwdInDb.length - SALT_LENGTH];//取得数据库中⼝令的消息摘要System.arraycopy(pwdInDb, SALT_LENGTH, digestInDb, 0, digestInDb.length);//⽐较根据输⼊⼝令⽣成的消息摘要和数据库中消息摘要是否相同if (Arrays.equals(digest, digestInDb)) {//⼝令正确返回⼝令匹配消息return true;} else {//⼝令不正确返回⼝令不匹配消息return false;}}catch(Exception e){throw new Exception("密码验证失败",e);}}/*** 将16进制字符串转换成字节数组(⼤写)* @param hex* @return*/public static byte[] hexStringToByte(String hex) {int len = (hex.length() / 2);byte[] result = new byte[len];char[] hexChars = hex.toCharArray();for (int i = 0; i < len; i++) {int pos = i * 2;result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4| HEX_NUMS_STR.indexOf(hexChars[pos + 1]));}return result;}public static void main(String[] args) throws Exception {//经过md5加盐加密的123字符串为str123// System.out.println(getEncryptedPwd("123"));String str123_1 = "3fc7ed92dfb924f56ece855e74bf9c5c0c1f6f72a4dcc4a7db943bf0";//123加盐加密 String str123_2 = "7dd3e5af8b373221a9864df5c2b46208fb819a256398a59deec5cb09";//123加盐加密 //⽐对输⼊登录秘密和数据库加盐加密密码boolean isTrue1 = validPassword("123",str123_1);boolean isTrue2 = validPassword("123",str123_2);boolean isTrue3 = validPassword("1231",str123_2);System.out.println("验证密码结果:"+isTrue1);//trueSystem.out.println("验证密码结果:"+isTrue2);//trueSystem.out.println("验证密码结果:"+isTrue3);//fase}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使用Java 生成MD5 编码
MD5即Message-Digest Algorithm 5(信息-摘要算法5),是一种用于产生数字签名的单项散列算法,在1991年由MIT Laboratory for Computer Science(IT计算机科学实验室)和RSA Data Security Inc(RSA数据安全公司)的Ronald L. Rivest教授开发出来,经由MD2、MD3和MD4发展而来。
MD5算法的使用不需要支付任何版权费用。
它的作用是让大容量信息在用数字签名软件签私人密匙前被"压缩"成一种保密的格式(将一个任意长度的“字节串”通过一个不可逆的字符串变换算法变换成一个128bit的大整数,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。
)
在Java 中,java.security.MessageDigest 中已经定义了MD5 的计算,所以我们只需要简单地调用即可得到MD5 的128 位整数。
然后将此128 位计16 个字节转换成16 进制表示即可。
代码如下:
package com.tsinghua;
/**
* MD5的算法在RFC1321 中定义
* 在RFC 1321中,给出了Test suite用来检验你的实现是否正确:
* MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
* MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
* MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
* MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
* MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
*
* @author haogj
*
* 传入参数:一个字节数组
* 传出参数:字节数组的MD5 结果字符串
*/
public class MD5 {
public static String getMD5(byte[] source) {
String s = null;
char hexDigits[] = { // 用来将字节转换成16 进制表示的字符
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
try
{
java.security.MessageDigest md = java.security.MessageDigest.getInstance( "MD5" );
md.update( source );
byte tmp[] = md.digest(); // MD5 的计算结果是一个128 位的长整数,
// 用字节表示就是16 个字节
char str[] = new char[16 * 2]; // 每个字节用16 进制表示的话,使用两个字符,
// 所以表示成16 进制需要32 个字符
int k = 0; // 表示转换结果中对应的字符位置
for (int i = 0; i < 16; i++) { // 从第一个字节开始,对MD5 的每一个字节
// 转换成16 进制字符的转换
byte byte0 = tmp[i]; // 取第i 个字节
str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字节中高4 位的数字转换, // >>> 为逻辑右移,将符号位一起右移str[k++] = hexDigits[byte0 & 0xf]; // 取字节中低4 位的数字转换}
s = new String(str); // 换后的结果转换为字符串
}catch( Exception e )
{
e.printStackTrace();
}
return s;
}
}
测试代码如下:
import com.tsinghua.*;
public class TestMD5
{
public static void main( String xu[] )
{ // 计算"a" 的MD5 代码,应该为:0cc175b9c0f1b6a831c399e269772661 System.out.println( MD5.getMD5("a".getBytes()) );
}
}。