Import java.lang.reflect.*; /************************************************* The MD5 class implements the RSA Data Security, Inc., which is submitted to the IETF The MD5 message-digest algorithm in the RFC1321. *************************************************/ public class MD5 { The following s11-s44 are actually a 4*4 matrix, which is written to facilitate the modification 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}; The following three members are the 3 core data used in the MD5 calculation, and in the original C implementation is defined in the MD5_CTX structure
Private long[] state = new LONG[4]; State (ABCD) Private long[] count = new long[2]; Number of bits, modulo 2^64 (LSB i) Private byte[] buffer = new BYTE[64]; Input buffer DIGESTHEXSTR is the only public member of the MD5, and is the most recently calculated 16 binary ASCII representation.
Public String Digesthexstr; Digest, a 2-in-system internal representation of the most recent results, representing the 128bit MD5 value.
Private byte[] Digest = new BYTE[16]; GETMD5OFSTR is the main public method of class MD5, and the entry parameter is the string you want to MD5 transform Returns the result of the transformation, which is obtained from the public member Digesthexstr.
public string Getmd5ofstr (string inbuf) { Md5init (); Md5update (Inbuf.getbytes (), inbuf.length ()); Md5final (); Digesthexstr = ""; for (int i = 0; i < i++) { Digesthexstr + + Bytehex (Digest[i]); } return digesthexstr; } This is the standard constructor for this class of MD5, JavaBean requires a constructor that is public and has no parameters Public MD5 () { Md5init (); Return } Md5init is an initialization function that initializes the core variable and loads the standard magic number
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 are 4 basic MD5 functions, in the original MD5 C implementation, because they are Simple bit operations, which can be implemented as macros for efficiency reasons, in Java, we Implemented as a private method, the name remains in the original C.
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 and II will call F,g,h,i for a near-step transformation Private Long FF (long A, long B, long C, long D, long X, Long S,long ac) { &nb sp; 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 is the MD5 of the main computing process, Inbuf is the byte string to transform, Inputlen is the length, this The function is called by the GETMD5OFSTR and calls the Md5init before it is called, so it is designed to be private
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 + < Inputlen i + = 64) { MD5MEMCPY (block, inbuf, 0, I, 64); Md5transform (block); } index = 0; } else i = 0; * Buffer remaining Input * * md5memcpy (buffer, INBUF, index, I, inputlen-i); } private void Md5final () { Byte[] bits = new BYTE[8]; int index, Padlen; * Save Number of bits * * Encode (Bits, count, 8); * Pad out to 64 mod. 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 is an internally used block copy function of the byte array, starting with the inpos of the input len length byte copy to Outpos position at output start
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 is the MD5 Core transformation program, with Md5update calls, block is a chunk of raw bytes
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 the long array into a byte array, because the long type of Java is 64bit, Only 32bit is removed to accommodate the original C implementation
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) >>>) & 0xffL); Output[j + 3] = (byte) ((Input[i] >>>) & 0xffL); } } Decode the byte array into a long array in order because the long type of Java is 64bit, Only synthesize low 32bit, high 32bit Zero, to adapt to the original C implementation of the use
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 is a "rise" program that puts byte in the principle of not considering the sign, because Java has no unsigned operation
public static long B2iu (byte b) { Return b < 0? B & 0x7F + 128:b; } Bytehex (), which converts the number of a byte type to an ASCII representation of the 16 binary, Because the byte in Java does not achieve this, we do not have the C language 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 string ToMD5 (string source) { MD5 MD5 = new MD5 (); return md5.getmd5ofstr (source); } }
The result is a 32-bit encrypted string, in some instances the 8--24 bit of the cipher string is intercepted and the length is 16 bits. /////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////// The second method of "reference" article byAlgorithm source Bar (www.sfcode.cn)Collect MD5 encryption algorithm is strict, security is high, widely used in system authentication, file integrity verification. The Java API contains the MessageDigest class in the Java.security package, which enables a simple application of the MD5 algorithm, such as converting the specified plain text to a MD5 password, with the reference source code as follows: /* ************************************************************* * Project:bobtoolkit <p> * Package:bob.sec.MD5 <p> * filename:md5util.java<p> * Created by Bobchen on 2007-3-29 <p> * //////////////////////////////////////////////////////////// * Date Author Description * 2007-3-29 Bobchen Init:object md5util * ***********************************************************/ Package bob.sec.MD5;
Import Java.security.MessageDigest;
public class Md5util { Public final static string MD5 (string s) { Char hexdigits[] = {' 0 ', ' 1 ', ' 2 ', ' 3 ', ' 4 ', ' 5 ', ' 6 ', ' 7 ', ' 8 ', ' 9 ', ' A ', ' B ', ' C ', ' D ', ' E ', ' F '}; try { byte[] Btinput = S.getbytes (); MessageDigest mdinst = messagedigest.getinstance ("MD5"); Mdinst.update (Btinput); byte[] MD = Mdinst.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; } }
public static void Main (string[] args) { System.out.print (MD5UTIL.MD5 ("ausitcim#1485")); }
}
----------Run---------- Ef277661a4c821c9007acb52e1d883ec Output complete (time consuming 0 seconds)-Normal termination
----------------------JSP page calls-------------------------------
----------
String U_password=new string (Request.getparameter ("U_password"). GetBytes ("iso-8859-1"));
u_password= (New Md5util (). MD5 (U_password));
---------
String U_id=new string (Request.getparameter ("u_id"). GetBytes ("iso-8859-1"));
String U_password=new string (Request.getparameter ("U_password"). GetBytes ("iso-8859-1"));
u_password= (New Md5util (). MD5 (U_password)); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////// |