网站免费认证,wordpress用户组权限,网站制作学习网站,广东著名企业md5已经不安全了,中国山东大学女学霸王小云破解了一系列密码,当真是巾帼不让须眉.说是破解,其实就是给你一个md5码,让你求出这个md5码所对应的原始信息,显然一个md5对应无数种原始信息.而md5的特性就是难以还原初始信息,但是王小云可以迅速找到给定md5码的可行解.md5的解空间虽…md5已经不安全了,中国山东大学女学霸王小云破解了一系列密码,当真是巾帼不让须眉.说是破解,其实就是给你一个md5码,让你求出这个md5码所对应的原始信息,显然一个md5对应无数种原始信息.而md5的特性就是难以还原初始信息,但是王小云可以迅速找到给定md5码的可行解.md5的解空间虽然巨大,但是却难以捕捉到解. md5虽然已经不安全了,但是仍然可以用于校验. md5不是编码,编码是能够还原初始信息的,而md5只是固定的16byte,它只能从总体上反映初始信息的一些特征,却无法完整的还原出来,因为初始信息到md5码是一个多对一映射. md5中大量使用小头序,这点十分坑.还好java中有神奇伟大的ByteBuffer.ByteBuffer有四个索引:mark,limit,position,capacity. mark表示标记;limit表示position最大可以读到哪里;position表示当前位置;capacity表示最大容量. ByteBuffer这个类支持流式编程,比如put(byte)函数返回值仍然是ByteBuffer,这样就可以接着put了. ByteBuffer这个类最重要的就是4个指针,玩转了四个指针就学会了控制ByteBuffer,例如: flip()将limit置为当前position,将position置为0,准备从头读取数据,注意只能读取0~limit这一部分数据; rewind()将position置为0; mark()标记当前position,可以使用reset()将position重置为mark时的位置. compact()将当前postion之前的字节清空. clear()清空一切,将limit移动到copacity处,准备读入数据. 明白了如何操作这些指针,就明白了ByteBuffer. 当不了解md5的时候,听人们说md5的某些特性,觉得还是道听途说,只有亲自实现之后才能自己总结出md5有哪些特点. 下面给出md5信息摘要算法 import static java.lang.Math.abs;
import static java.lang.Math.floor;
import static java.lang.Math.pow;
import static java.lang.Math.sin;import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5 {// 移位的位数,分成4种,每种4个数,每种重复4次.不知道为啥是这些数字int[] s {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9,14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4,11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15,21, 6, 10, 15, 21, 6, 10, 15, 21};// 在init函数中初始化k[i]int k[] new int[64];void init() {for (int i 0; i 64; i) {long x (long) floor(abs(sin(i 1)) * pow(2, 32));k[i] (int) (x 0xffffffff);}}// 循环左移操作,比如4位的1011,循环左移一位相当于0110|1int leftRotate(int x, int n) {return (x n) | (x (32 - n));}byte[] digest(byte[] srcData) throws IOException {// 原数据字节数8byte的原始长度表示l,l有点偏短,如果它不是64的倍数,那么会舍弃一些,所以要加上一;如果它是64的倍数,那么需要补上一个字节,至少要添加一个chunk.// 一个chunk为64byte,其中最后一个chunk的前56byte为数据补齐的数据,最后8byte为long类型的数据,表示原始数据长度.// 整个md5都是基于小头序的int chunkCount (srcData.length 8) / 64 1;ByteBuffer buffer ByteBuffer.allocate(chunkCount * 64).order(ByteOrder.LITTLE_ENDIAN);buffer.put(srcData).put((byte) 0x80).position(buffer.limit() - 8);buffer.putLong(8 * srcData.length).flip();//flip准备读取数据int a0 0x67452301, b0 0xefcdab89, c0 0x98badcfe, d0 0x10325476;while (buffer.hasRemaining()) {int m[] new int[16];for (int i 0; i 16; i) {m[i] buffer.getInt();}int a a0, b b0, c c0, d d0;int f, g;for (int i 0; i 64; i) {if (i 16) {f (b c) | (~b d);g i;} else if (i 32) {f (d b) | (~d c);g (5 * i 1) % 16;} else if (i 48) {f b ^ c ^ d;g (3 * i 5) % 16;} else {f c ^ (b | ~d);g (7 * i) % 16;}int dd d;d c;c b;b b leftRotate(a f k[i] m[g], s[i]);a dd;}a0 a;b0 b;c0 c;d0 d;}return ByteBuffer.allocate(16).order(ByteOrder.LITTLE_ENDIAN).putInt(a0).putInt(b0).putInt(c0).putInt(d0).array();}static void show(byte[] b) {for (byte i : b) {System.out.printf(%02X, i);}System.out.println();}public static void main(String[] args)throws NoSuchAlgorithmException, IOException {byte[] b 魏印福.getBytes();MessageDigest md5 MessageDigest.getInstance(MD5);md5.update(b);byte[] res md5.digest();show(res);MD5 m new MD5();m.init();res m.digest(b);show(res);}
} 跟md5一样,SHA也有好多版本,SHA1,SHA2,SHA3,其中SHA2,SHA3又分成了好多版本.SHA加密强度比md5更强,它名叫Secure Hash Algorithm.md5校验码位长相当于4个int,SHA的位长相当于5个int.二者都是以64Byte为一个chunk进行处理. 下面给出java中如何使用库函数自带的SHA public class SHA {static String tos(byte[] b) {String ans ;for (int i 0; i b.length; i) {ans String.format(%02X, b[i]);}return ans;}public static void main(String[] args) throws Exception {byte[] data 魏印福.getBytes();MessageDigest digest MessageDigest.getInstance(SHA);byte[] ans digest.digest(data);System.out.println(tos(ans));System.out.println(tos(MessageDigest.getInstance(SHA-1).digest(data)));}
}