java

位置:IT落伍者 >> java >> 浏览文章

可变MD5加密(Java实现)


发布日期:2024年08月18日
 
可变MD5加密(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[]));

}

}

               

上一篇:编程技巧:Java串口通信简介

下一篇:如何防止JAVA程序源代码被反编译