可变MD5加密(Java实现)

Python012

可变MD5加密(Java实现),第1张

可变在这里含义很简单 就是最终的加密结果是可变的 而非必需按标准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 = partLeni + <inputLeni += ) {

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 <leni++)

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 <leni++ 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 <leni++ 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

JDK里面有一个java.security.MessageDigest类,这个类就是用来加密的。

加密代码如下:

String token = System.currentTimeMillis()+new Random().nextInt()+""

try {

MessageDigest md = MessageDigest.getInstance("MD5")

byte[] md5 = md.digest(token.getBytes())

} catch (Exception e) {

throw new RuntimeException(e)

}

这个byte类型的数组就是使用MD5加密后的结果