熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

可變MD5加密(Java實現)

2022-06-13   來源: Java核心技術 

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

  Java代碼

  package ****util;

  import javasecurityMessageDigest;

  /**

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

  * @author Sarin

  */

  public class MD {

  /**

  * 獲得MD加密密碼的方法

  */

  public static String getMDofStr(String origString) {

  String origMD = null;

  try {

  MessageDigest md = MessageDigestgetInstance(MD);

  byte[] result = mddigest(origStringgetBytes());

  origMD = byteArrayHexStr(result);

  } catch (Exception e) {

  eprintStackTrace();

  }

  return origMD;

  }

  /**

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

  */

  private static String byteArrayHexStr(byte[] bs) {

  StringBuffer sb = new StringBuffer();

  for (byte b : bs) {

  sbappend(byteHexStr(b));

  }

  return sbtoString();

  }

  /**

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

  */

  private static String byteHexStr(byte b) {

  String hexStr = null;

  int n = b;

  if (n < ) {

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

  n = b & xF + ;

  }

  hexStr = IntegertoHexString(n / ) + IntegertoHexString(n % );

  return hexStrtoUpperCase();

  }

  /**

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

  */

  public static String getMDofStr(String origString int times) {

  String md = getMDofStr(origString);

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

  md = getMDofStr(md);

  }

  return getMDofStr(md);

  }

  /**

  * 密碼驗證方法

  */

  public static boolean verifyPassword(String inputStr String MDCode) {

  return getMDofStr(inputStr)equals(MDCode);

  }

  /**

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

  */

  public static boolean verifyPassword(String inputStr String MDCode int times) {

  return getMDofStr(inputStr times)equals(MDCode);

  }

  /**

  * 提供一個測試的主函數

  */

  public static void main(String[] args) {

  Systemoutprintln(: + getMDofStr());

  Systemoutprintln(: + getMDofStr());

  Systemoutprintln(sarin: + getMDofStr(sarin));

  Systemoutprintln(: + getMDofStr( ));

  }

  }

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

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

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

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

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

  Java代碼

  import javalangreflect*;

  /**

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

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

  * 的RFC中的MD messagedigest 算法

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

  */

  public class MD {

  /* 下面這些SS實際上是一個*的矩陣在原始的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 ^ (lsb first)

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

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

  進制ASCII表示

  */

  public String digestHexStr;

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

  */

  private byte[] digest = new byte[];

  /*

  getMDofStr是類MD最主要的公共方法入口參數是你想要進行MD變換的字符串

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

  */

  public String getMDofStr(String inbuf) {

  mdInit();

  mdUpdate(inbufgetBytes() inbuflength());

  mdFinal();

  digestHexStr = ;

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

  digestHexStr += byteHEX(digest[i]);

  }

  return digestHexStr;

  }

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

  public MD() {

  mdInit();

  return;

  }

  /* mdInit是一個初始化函數初始化核心變量裝入標准的幻數 */

  private void mdInit() {

  count[] = L;

  count[] = L;

  ///* Load magic initialization constants

  state[] = xL;

  state[] = xefcdabL;

  state[] = xbadcfeL;

  state[] = xL;

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

  }

  /*

  FFGGHH和II將調用FGHI進行近一步變換

  FF GG HH and II transformations for rounds and

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

  }

  /*

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

  函數由getMDofStr調用調用之前需要調用mdinit因此把它設計成private的

  */

  private void mdUpdate(byte[] inbuf int inputLen) {

  int i index partLen;

  byte[] block = new byte[];

  index = (int) (count[] >>> ) & xF;

  // /* Update number of bits */

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

  count[]++;

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

  partLen = index;

  // Transform as many times as possible

  if (inputLen >= partLen) {

  mdMemcpy(buffer inbuf index partLen);

  mdTransform(buffer);

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

  mdMemcpy(block inbuf i );

  mdTransform(block);

  }

  index = ;

  } else

  i = ;

  ///* Buffer remaining input */

  mdMemcpy(buffer inbuf index i inputLen i);

  }

  /*

  mdFinal整理和填寫輸出結果

  */

  private void mdFinal() {

  byte[] bits = new byte[];

  int index padLen;

  ///* Save number of bits */

  Encode(bits count );

  ///* Pad out to mod

  index = (int) (count[] >>> ) & xf;

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

  mdUpdate(PADDING padLen);

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

  mdUpdate(bits );

  ///* Store state in digest */

  Encode(digest state );

  }

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

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

  */

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

  int i;

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

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

  }

  /*

  mdTransform是MD核心變換程序有mdUpdate調用block是分塊的原始字節

  */

  private void mdTransform(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 xdaaL); /* */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /* Round */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /* Round */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /* Round */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  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的

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

  */

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

  int i j;

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

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

  | (biu(input[j + ]) << );

  return;

  }

  /*

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

  */

  public static long biu(byte b) {

  return b < ? b & xF + : b;

  }

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

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

  sprintf(outbuf%Xib)

  */

  public static String byteHEX(byte ib) {

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

  char[] ob = new char[];

  ob[] = Digit[(ib >>> ) & XF];

  ob[] = Digit[ib & XF];

  String s = new String(ob);

  return s;

  }

  public static void main(String args[]) {

  MD m = new MD();

  if (ArraygetLength(args) == ) { //如果沒有參數執行標准的Test Suite

  Systemoutprintln(MD Test suite:);

  Systemoutprintln(MD(\\): + mgetMDofStr());

  Systemoutprintln(MD(\a\): + mgetMDofStr(a));

  Systemoutprintln(MD(\abc\): + mgetMDofStr(abc));

  Systemoutprintln(MD(\\): + mgetMDofStr());

  Systemoutprintln(MD(\\): + mgetMDofStr());

  Systemoutprintln(MD(\message digest\): + mgetMDofStr(message digest));

  Systemoutprintln(MD(\abcdefghijklmnopqrstuvwxyz\): + mgetMDofStr(abcdefghijklmnopqrstuvwxyz));

  Systemoutprintln(MD(\ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\):

  + mgetMDofStr(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz));

  } else

  Systemoutprintln(MD( + args[] + )= + mgetMDofStr(args[]));

  }

  }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26604.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.