古詩詞大全網 - 藝術簽名 - 可變MD5加密(Java實現)

可變MD5加密(Java實現)

 可變在這裏含義很簡單 就是最終的加密結果是可變的 而非必需按標準MD 加密實現 Java類庫security中的MessageDigest類就提供了MD 加密的支持 實現起來非常方便 為了實現更多效果 我們可以如下設計MD 工具類

 Java代碼

 package ** ** util;

 import java security MessageDigest;

 /**

 * 標準MD 加密方法 使用java類庫的security包的MessageDigest類處理

 * @author Sarin

 */

 public class MD {

 /**

 * 獲得MD 加密密碼的方法

 */

 public static String getMD ofStr(String origString) {

 String origMD = null;

 try {

 MessageDigest md = MessageDigest getInstance( MD );

 byte[] result = md digest(origString getBytes());

 origMD = byteArray HexStr(result);

 } catch (Exception e) {

 e printStackTrace();

 }

 return origMD ;

 }

 /**

 * 處理字節數組得到MD 密碼的方法

 */

 private static String byteArray HexStr(byte[] bs) {

 StringBuffer *** = new StringBuffer();

 for (byte b : bs) {

  *** append(byte HexStr(b));

 }

 return *** toString();

 }

 /**

 * 字節標準移位轉十六進制方法

 */

 private static String byte HexStr(byte b) {

 String hexStr = null;

 int n = b;

 if (n < ) {

 //若需要自定義加密 請修改這個移位算法即可

 n = b & x F + ;

 }

 hexStr = Integer toHexString(n / ) + Integer toHexString(n % );

 return hexStr toUpperCase();

 }

 /**

 * 提供壹個MD 多次加密方法

 */

 public static String getMD ofStr(String origString int times) {

 String md = getMD ofStr(origString);

 for (int i = ; i < times ; i++) {

 md = getMD ofStr(md );

 }

 return getMD ofStr(md );

 }

 /**

 * 密碼驗證方法

 */

 public static boolean verifyPassword(String inputStr String MD Code) {

 return getMD ofStr(inputStr) equals(MD Code);

 }

 /**

 * 重載壹個多次加密時的密碼驗證方法

 */

 public static boolean verifyPassword(String inputStr String MD Code int times) {

 return getMD ofStr(inputStr times) equals(MD Code);

 }

 /**

 * 提供壹個測試的主函數

 */

 public static void main(String[] args) {

 System out println( : + getMD ofStr( ));

 System out println( : + getMD ofStr( ));

 System out println( sarin: + getMD ofStr( sarin ));

 System out println( : + getMD ofStr( ));

 }

 }

 可以看出實現的過程非常簡單 因為由java類庫提供了處理支持 但是要清楚的是這種方式產生的密碼不是標準的MD 碼 它需要進行移位處理才能得到標準MD 碼 這個程序的關鍵之處也在這了 怎麽可變?調整移位算法不就可變了麽!不進行移位 也能夠得到 位的密碼 這就不是標準加密了 只要加密和驗證過程使用相同的算法就可以了

 MD 加密還是很安全的 像CMD 那些窮舉破解的只是針對標準MD 加密的結果進行的 如果自定義移位算法後 它還有效麽?可以說是無解的了 所以MD 非常安全可靠

 為了更可變 還提供了多次加密的方法 可以在MD 基礎之上繼續MD 就是對 位的第壹次加密結果再MD 恩 這樣去破解?沒有任何意義

 這樣在MIS系統中使用 安全可靠 歡迎交流 希望對使用者有用

 我們最後看看由MD 加密算法實現的類 那是非常龐大的

 Java代碼

 import java lang reflect *;

 /**

 * **********************************************

 * md 類實現了RSA Data Security Inc 在提交給IETF

 * 的RFC 中的MD message digest 算法

 * ***********************************************

 */

 public class MD {

 /* 下面這些S S 實際上是壹個 * 的矩陣 在原始的C實現中是用#define 實現的

 這裏把它們實現成為static final是表示了只讀 切能在同壹個進程空間內的多個

 Instance間***享*/

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final int S = ;

 static final byte[] PADDING = {

 

  };

 /* 下面的三個成員是MD 計算過程中用到的 個核心數據 在原始的C實現中

 被定義到MD _CTX結構中

 */

 private long[] state = new long[ ]; // state (ABCD)

 private long[] count = new long[ ]; // number of bits modulo ^ (l *** first)

 private byte[] buffer = new byte[ ]; // input buffer

 /* digestHexStr是MD 的唯壹壹個公***成員 是最新壹次計算結果的

  進制ASCII表示

 */

 public String digestHexStr;

 /* digest 是最新壹次計算結果的 進制內部表示 表示 bit的MD 值

 */

 private byte[] digest = new byte[ ];

 /*

 getMD ofStr是類MD 最主要的公***方法 入口參數是妳想要進行MD 變換的字符串

 返回的是變換完的結果 這個結果是從公***成員digestHexStr取得的.

 */

 public String getMD ofStr(String inbuf) {

 md Init();

 md Update(inbuf getBytes() inbuf length());

 md Final();

 digestHexStr = ;

 for (int i = ; i < ; i++) {

 digestHexStr += byteHEX(digest[i]);

 }

 return digestHexStr;

 }

 // 這是MD 這個類的標準構造函數 JavaBean要求有壹個public的並且沒有參數的構造函數

 public MD () {

 md Init();

 return;

 }

 /* md Init是壹個初始化函數 初始化核心變量 裝入標準的幻數 */

 private void md Init() {

 count[ ] = L;

 count[ ] = L;

 ///* Load magic initialization constants

 state[ ] = x L;

 state[ ] = xefcdab L;

 state[ ] = x badcfeL;

 state[ ] = x L;

 return;

 }

 /* F G H I 是 個基本的MD 函數 在原始的MD 的C實現中 由於它們是

 簡單的位運算 可能出於效率的考慮把它們實現成了宏 在java中 我們把它們

 實現成了private方法 名字保持了原來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和II將調用F G H I進行近壹步變換

 FF GG HH and II transformations for rounds and

 Rotation is separate from addition to prevent reputation

 */

 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 >>> ( 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 >>> ( 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 >>> ( 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 >>> ( s));

 a += b;

 return a;

 }

 /*

 md Update是MD 的主計算過程 inbuf是要變換的字節串 inputlen是長度 這個

 函數由getMD ofStr調用 調用之前需要調用md init 因此把它設計成private的

 */

 private void md Update(byte[] inbuf int inputLen) {

 int i index partLen;

 byte[] block = new byte[ ];

 index = (int) (count[ ] >>> ) & x F;

 // /* Update number of bits */

 if ((count[ ] += (inputLen << )) < (inputLen << ))

 count[ ]++;

 count[ ] += (inputLen >>> );

 partLen = index;

 // Transform as many times as possible

 if (inputLen >= partLen) {

 md Memcpy(buffer inbuf index partLen);

 md Transform(buffer);

 for (i = partLen; i + < inputLen; i += ) {

 md Memcpy(block inbuf i );

 md Transform(block);

 }

 index = ;

 } else

 i = ;

 ///* Buffer remaining input */

 md Memcpy(buffer inbuf index i inputLen i);

 }

 /*

 md Final整理和填寫輸出結果

 */

 private void md Final() {

 byte[] bits = new byte[ ];

 int index padLen;

 ///* Save number of bits */

 Encode(bits count );

 ///* Pad out to mod

 index = (int) (count[ ] >>> ) & x f;

 padLen = (index < ) ? ( index) : ( index);

 md Update(PADDING padLen);

 ///* Append length (before padding) */

 md Update(bits );

 ///* Store state in digest */

 Encode(digest state );

 }

 /* md Memcpy是壹個內部使用的byte數組的塊拷貝函數 從input的inpos開始把len長度的

 字節拷貝到output的outpos位置開始

 */

 private void md Memcpy(byte[] output byte[] input int outpos int inpos int len) {

 int i;

 for (i = ; i < len; i++)

 output[outpos + i] = input[inpos + i];

 }

 /*

 md Transform是MD 核心變換程序 有md Update調用 block是分塊的原始字節

 */

 private void md Transform(byte block[]) {

 long a = state[ ] b = state[ ] c = state[ ] d = state[ ];

 long[] x = new long[ ];

 Decode(x block );

 /* Round */

 a = FF(a b c d x[ ] S xd aa L); /* */

 d = FF(d a b c x[ ] S xe c b L); /* */

 c = FF(c d a b x[ ] S x dbL); /* */

 b = FF(b c d a x[ ] S xc bdceeeL); /* */

 a = FF(a b c d x[ ] S xf c fafL); /* */

 d = FF(d a b c x[ ] S x c aL); /* */

 c = FF(c d a b x[ ] S xa L); /* */

 b = FF(b c d a x[ ] S xfd L); /* */

 a = FF(a b c d x[ ] S x d L); /* */

 d = FF(d a b c x[ ] S x b f afL); /* */

 c = FF(c d a b x[ ] S xffff bb L); /* */

 b = FF(b c d a x[ ] S x cd beL); /* */

 a = FF(a b c d x[ ] S x b L); /* */

 d = FF(d a b c x[ ] S xfd L); /* */

 c = FF(c d a b x[ ] S xa eL); /* */

 b = FF(b c d a x[ ] S x b L); /* */

 /* Round */

 a = GG(a b c d x[ ] S xf e L); /* */

 d = GG(d a b c x[ ] S xc b L); /* */

 c = GG(c d a b x[ ] S x e a L); /* */

 b = GG(b c d a x[ ] S xe b c aaL); /* */

 a = GG(a b c d x[ ] S xd f dL); /* */

 d = GG(d a b c x[ ] S x L); /* */

 c = GG(c d a b x[ ] S xd a e L); /* */

 b = GG(b c d a x[ ] S xe d fbc L); /* */

 a = GG(a b c d x[ ] S x e cde L); /* */

 d = GG(d a b c x[ ] S xc d L); /* */

 c = GG(c d a b x[ ] S xf d d L); /* */

 b = GG(b c d a x[ ] S x a edL); /* */

 a = GG(a b c d x[ ] S xa e e L); /* */

 d = GG(d a b c x[ ] S xfcefa f L); /* */

 c = GG(c d a b x[ ] S x f d L); /* */

 b = GG(b c d a x[ ] S x d a c aL); /* */

 /* Round */

 a = HH(a b c d x[ ] S xfffa L); /* */

 d = HH(d a b c x[ ] S x f L); /* */

 c = HH(c d a b x[ ] S x d d L); /* */

 b = HH(b c d a x[ ] S xfde cL); /* */

 a = HH(a b c d x[ ] S xa beea L); /* */

 d = HH(d a b c x[ ] S x bdecfa L); /* */

 c = HH(c d a b x[ ] S xf bb b L); /* */

 b = HH(b c d a x[ ] S xbebfbc L); /* */

 a = HH(a b c d x[ ] S x b ec L); /* */

 d = HH(d a b c x[ ] S xeaa faL); /* */

 c = HH(c d a b x[ ] S xd ef L); /* */

 b = HH(b c d a x[ ] S x d L); /* */

 a = HH(a b c d x[ ] S xd d d L); /* */

 d = HH(d a b c x[ ] S xe db e L); /* */

 c = HH(c d a b x[ ] S x fa cf L); /* */

 b = HH(b c d a x[ ] S xc ac L); /* */

 /* Round */

 a = II(a b c d x[ ] S xf L); /* */

 d = II(d a b c x[ ] S x aff L); /* */

 c = II(c d a b x[ ] S xab a L); /* */

 b = II(b c d a x[ ] S xfc a L); /* */

 a = II(a b c d x[ ] S x b c L); /* */

 d = II(d a b c x[ ] S x f ccc L); /* */

 c = II(c d a b x[ ] S xffeff dL); /* */

 b = II(b c d a x[ ] S x dd L); /* */

 a = II(a b c d x[ ] S x fa e fL); /* */

 d = II(d a b c x[ ] S xfe ce e L); /* */

 c = II(c d a b x[ ] S xa L); /* */

 b = II(b c d a x[ ] S x e a L); /* */

 a = II(a b c d x[ ] S xf e L); /* */

 d = II(d a b c x[ ] S xbd af L); /* */

 c = II(c d a b x[ ] S x ad d bbL); /* */

 b = II(b c d a x[ ] S xeb d L); /* */

 state[ ] += a;

 state[ ] += b;

 state[ ] += c;

 state[ ] += d;

 }

 /*Encode把long數組按順序拆成byte數組 因為java的long類型是 bit的

 只拆低 bit 以適應原始C實現的用途

 */

 private void Encode(byte[] output long[] input int len) {

 int i j;

 for (i = j = ; j < len; i++ j += ) {

 output[j] = (byte) (input[i] & xffL);

 output[j + ] = (byte) ((input[i] >>> ) & xffL);

 output[j + ] = (byte) ((input[i] >>> ) & xffL);

 output[j + ] = (byte) ((input[i] >>> ) & xffL);

 }

 }

 /*Decode把byte數組按順序合成成long數組 因為java的long類型是 bit的

 只合成低 bit 高 bit清零 以適應原始C實現的用途

 */

 private void Decode(long[] output byte[] input int len) {

 int i j;

 for (i = j = ; j < len; i++ j += )

 output[i] = b iu(input[j]) | (b iu(input[j + ]) << ) | (b iu(input[j + ]) << )

 | (b iu(input[j + ]) << );

 return;

 }

 /*

 b iu是我寫的壹個把byte按照不考慮正負號的原則的"升位"程序 因為java沒有unsigned運算

 */

 public static long b iu(byte b) {

 return b < ? b & x F + : b;

 }

 /*byteHEX() 用來把壹個byte類型的數轉換成十六進制的ASCII表示

 因為java中的byte的toString無法實現這壹點 我們又沒有C語言中的

 sprintf(outbuf % X ib)

 */

 public static String byteHEX(byte ib) {

 char[] Digit = { A B C D E F };

 char[] ob = new char[ ];

 ob[ ] = Digit[(ib >>> ) & X F];

 ob[ ] = Digit[ib & X F];

 String s = new String(ob);

 return s;

 }

 public static void main(String args[]) {

 MD m = new MD ();

 if (Array getLength(args) == ) { //如果沒有參數 執行標準的Test Suite

 System out println( MD Test suite: );

 System out println( MD (\ \ ): + m getMD ofStr( ));

 System out println( MD (\ a\ ): + m getMD ofStr( a ));

 System out println( MD (\ abc\ ): + m getMD ofStr( abc ));

 System out println( MD (\ \ ): + m getMD ofStr( ));

 System out println( MD (\ \ ): + m getMD ofStr( ));

 System out println( MD (\ message digest\ ): + m getMD ofStr( message digest ));

 System out println( MD (\ abcdefghijklmnopqrstuvwxyz\ ): + m getMD ofStr( abcdefghijklmnopqrstuvwxyz ));

 System out println( MD (\ ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz \ ):

 + m getMD ofStr( ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ));

 } else

 System out println( MD ( + args[ ] + )= + m getMD ofStr(args[ ]));

 }

lishixinzhi/Article/program/Java/hx/201311/26604