md5碰撞Java_2 MD5加密 java实现

百度百科对MD5的说明是:

Message Digest Algorithm MD5(中文名为消息摘要算法第 五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。

MD5算法具有以下特点:

1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。

2、容易计算:从原数据计算出MD5值很容易。

3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。

通常采用java提供的API实现的MD5加密程序如下所示:

1 importjava.security.MessageDigest;2 importjava.security.NoSuchAlgorithmException;3

4

5 public classEncryption1 {6 public static final String MD5="MD5";7 /**

8 * 采用加密算法加密字符串数据9 *@paramstr 需要加密的数据10 *@paramalgorithm 采用的加密算法11 *@return字节数据12 */

13 public static byte[] EncryptionStr(String str, String algorithm) {14 //加密之后所得字节数组

15 byte[] bytes = null;16 try{17 //获取MD5算法实例 得到一个md5的消息摘要

18 MessageDigest md =MessageDigest.getInstance(algorithm);19 //添加要进行计算摘要的信息

20 md.update(str.getBytes());21 //得到该摘要

22 bytes =md.digest();23 } catch(NoSuchAlgorithmException e) {24 System.out.println("加密算法: "+ algorithm +" 不存在: ");25 }26 return null==bytes?null:bytes;27 }28 //测试上述方法

29 public static voidmain(String[] args) {30 String test1="test1";31 String test2="QWERFVDSCX";32 String test3="23423KJHkdfg";33 String [] test={test1,test2,test3};34 for(String s : test) {35 byte [] bytes=EncryptionStr(s,MD5);36 System.out.println("数据:" + s+" 加密之后的结果为:"+bytes.toString()+" 字节数组长度为:"+bytes.length);37 }38 }39 }

上述代码执行结果为:

1 数据:test1 加密之后的结果为:[B@71881149 字节数组长度为:16

2 数据:QWERFVDSCX 加密之后的结果为:[B@1c2709da 字节数组长度为:16

3 数据:23423KJHkdfg 加密之后的结果为:[B@46f7d5a6 字节数组长度为:16

分析:字符串采用MD5加密之后返回的数据类型为字节数组(byte []),一个字节是8位(bit位),返回的数组长度是16,那么加密的字符串结果为16*8=128位,为固定长度的字节数组,除了MD5代码之外,上述代码中algorithm参数改成SHA-1 、SHA-256等加密算法也是支持的

上述加密结果通常转成长度为32的字符串进行存储和传输,下面是程序代码:

1 importjava.security.MessageDigest;2 importjava.security.NoSuchAlgorithmException;3

4 public classEncryption2 {5 public static final String MD5="MD5";6

7 /**

8 * 采用加密算法加密字符串数据9 *@paramstr 需要加密的数据10 *@paramalgorithm 采用的加密算法11 *@return字节数据12 */

13 public static byte[] EncryptionStrBytes(String str, String algorithm) {14 //加密之后所得字节数组

15 byte[] bytes = null;16 try{17 //获取MD5算法实例 得到一个md5的消息摘要

18 MessageDigest md =MessageDigest.getInstance(algorithm);19 //添加要进行计算摘要的信息

20 md.update(str.getBytes());21 //得到该摘要

22 bytes =md.digest();23 } catch(NoSuchAlgorithmException e) {24 System.out.println("加密算法: "+ algorithm +" 不存在: ");25 }26 return null==bytes?null:bytes;27 }28

29

30

31 /**

32 * 把字节数组转化成字符串返回33 *@parambytes34 *@return

35 */

36 public static String BytesConvertToHexString(byte[] bytes) {37 StringBuffer sb = newStringBuffer();38 for (byteaByte : bytes) {39 String s=Integer.toHexString(0xff &aByte);40 if(s.length()==1){41 sb.append("0"+s);42 }else{43 sb.append(s);44 }45 }46 returnsb.toString();47 }48

49 /**

50 * 采用加密算法加密字符串数据51 *@paramstr 需要加密的数据52 *@paramalgorithm 采用的加密算法53 *@return字节数据54 */

55 public staticString EncryptionStr(String str, String algorithm) {56 //加密之后所得字节数组

57 byte[] bytes =EncryptionStrBytes(str,algorithm);58 returnBytesConvertToHexString(bytes);59 }60 //测试上述方法

61 public static voidmain(String[] args) {62 String test1="test1";63 String test2="QWERFVDSCX";64 String test3="23423KJHkdfg";65 String [] test={test1,test2,test3};66 for(String s : test) {67 String str=EncryptionStr(s,MD5);68 System.out.println("数据:" + s+" 加密之后的结果为:"+str+" 字符串长度为:"+str.length());69 }70 }71 }

上述代码执行结果为:

1 数据:test1 加密之后的结果为:5a105e8b9d40e1329780d62ea2265d8a 字符串长度为:32

2 数据:QWERFVDSCX 加密之后的结果为:ce5b403e336fb819b48b08dbfd39fbf3 字符串长度为:32

3 数据:23423KJHkdfg 加密之后的结果为:6a91f81e7809f6f79c753a054543d128 字符串长度为:32

上述代码虽然实现了基本的数据加密功能,但是有人可能觉得32位字符串还是太长了,想改成16位或者其他长度;或者说java编码时工程统一使用UTF-8编码,对字符串编码格式进行指定等要求,下面是一种实现(功能可扩充点还有很多,比如说字符串数组加密,把加密之后的数据转成指定编码格式等)

1 importjava.io.UnsupportedEncodingException;2 importjava.security.MessageDigest;3 importjava.security.NoSuchAlgorithmException;4

5 public classEncryption3 {6 public static final String MD5="MD5";7 public static final String UTF8="UTF-8";8

9 /**

10 * 采用加密算法加密字符串数据 转成长度为32的字符串11 *@paramstr12 *@paramalgorithm 采用的加密算法13 *@paramcharset 指定转化之后的字符串编码14 *@return

15 */

16 public staticString EncryptionStr32(String str, String algorithm,String charset) {17 //加密之后所得字节数组

18 byte[] bytes =EncryptionStrBytes(str,algorithm,charset);19 returnBytesConvertToHexString(bytes);20 }21

22 /**

23 * 采用加密算法加密字符串数据 转成长度为32的字符串24 *@paramstr 需要加密的数据25 *@paramalgorithm 采用的加密算法26 *@return字节数据27 */

28 public staticString EncryptionStr32(String str, String algorithm) {29 return EncryptionStr32(str,algorithm,"");30 }31

32

33 /**

34 * 采用加密算法加密字符串数据 转成长度为16的字符串35 *@paramstr36 *@paramalgorithm 采用的加密算法37 *@paramcharset 指定转化之后的字符串编码38 *@return

39 */

40 public staticString EncryptionStr16(String str, String algorithm,String charset) {41 return EncryptionStr32(str,algorithm,charset).substring(8,24);42 }43

44 /**

45 * 采用加密算法加密字符串数据 转成长度为16的字符串46 *@paramstr 需要加密的数据47 *@paramalgorithm 采用的加密算法48 *@return字节数据49 */

50 public staticString EncryptionStr16(String str, String algorithm) {51 return EncryptionStr32(str,algorithm,"").substring(8,24);52 }53

54 /**

55 * 采用加密算法加密字符串数据56 *@paramstr 需要加密的数据57 *@paramalgorithm 采用的加密算法58 *@paramcharset 指定转化之后的字符串编码59 *@return字节数据60 */

61 public static byte[] EncryptionStrBytes(String str, String algorithm, String charset) {62 //加密之后所得字节数组

63 byte[] bytes = null;64 try{65 //获取MD5算法实例 得到一个md5的消息摘要

66 MessageDigest md =MessageDigest.getInstance(algorithm);67 //添加要进行计算摘要的信息

68 if(null==charset||"".equals(charset)) {69 md.update(str.getBytes());70 }else{71 md.update(str.getBytes(charset));72 }73 //得到该摘要

74 bytes =md.digest();75 } catch(NoSuchAlgorithmException e) {76 System.out.println("加密算法: "+ algorithm +" 不存在: ");77 } catch(UnsupportedEncodingException e) {78 System.out.println("数据加密指定的编码格式不支持: " +charset);79 }80 return null==bytes?null:bytes;81 }82 /**

83 * 把字节数组转化成字符串返回84 *@parambytes85 *@return

86 */

87 public static String BytesConvertToHexString(byte[] bytes) {88 StringBuffer sb = newStringBuffer();89 for (byteaByte : bytes) {90 String s=Integer.toHexString(0xff &aByte);91 if(s.length()==1){92 sb.append("0"+s);93 }else{94 sb.append(s);95 }96 }97 returnsb.toString();98 }99

100 //测试上述方法

101 public static voidmain(String[] args) {102 String test1="test1";103 String test2="QWERFVDSCX";104 String test3="23423KJHkdfg";105 String [] test={test1,test2,test3};106 for(String s : test) {107 String str=EncryptionStr32(s, MD5, UTF8);108 System.out.println("数据:" + s+" 加密之后的结果为:"+str+" 字符串长度为:"+str.length());109 str =EncryptionStr16(s, MD5, UTF8);110 System.out.println("数据:" + s+" 加密之后的结果为:"+str+" 字符串长度为:"+str.length());111 }112 }113 }

程序运行结果:

1 数据:test1 加密之后的结果为:5a105e8b9d40e1329780d62ea2265d8a 字符串长度为:32

2 数据:test1 加密之后的结果为:9d40e1329780d62e 字符串长度为:16

3 数据:QWERFVDSCX 加密之后的结果为:ce5b403e336fb819b48b08dbfd39fbf3 字符串长度为:32

4 数据:QWERFVDSCX 加密之后的结果为:336fb819b48b08db 字符串长度为:16

5 数据:23423KJHkdfg 加密之后的结果为:6a91f81e7809f6f79c753a054543d128 字符串长度为:32

6 数据:23423KJHkdfg 加密之后的结果为:7809f6f79c753a05 字符串长度为:16

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sha碰撞,MD5碰撞实现,#!/usr/local/bin/perl # It was noted that Intel IA-32 C compiler generates code which # performs ~30% *faster* on P4 CPU than original *hand-coded* # SHA1 assembler implementation. To address this problem (and # prove that humans are still better than machines:-), the # original code was overhauled, which resulted in following # performance changes: # # compared with original compared with Intel cc # assembler impl. generated code # Pentium -25% +37% # PIII/AMD +8% +16% # P4 +85%(!) +45% # # As you can see Pentium came out as looser:-( Yet I reckoned that # improvement on P4 outweights the loss and incorporate this # re-tuned code to 0.9.7 and later. # ---------------------------------------------------------------- # Those who for any particular reason absolutely must score on # Pentium can replace this module with one from 0.9.6 distribution. # This "offer" shall be revoked the moment programming interface to # this module is changed, in which case this paragraph should be # removed. # ---------------------------------------------------------------- # $normal=0; push(@INC,"perlasm","../../perlasm"); require "x86asm.pl"; &asm_init($ARGV[0],"sha1-586.pl",$ARGV[$#ARGV] eq "386"); $A="eax"; $B="ecx"; $C="ebx"; $D="edx"; $E="edi"; $T="esi"; $tmp1="ebp"; $off=9*4; @K=(0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6); &sha1_block_data("sha1_block_asm_data_order"); &asm_finish(); sub Nn { local($p)=@_; local(%n)=($A,$T,$B,$A,$C,$B,$D,$C,$E,$D,$T,$E); return($n{$p}); } sub Np { local($p)=@_; local(%n)=($A,$T,$B,$A,$C,$B,$D,$C,$E,$D,$T,$E); local(%n)=($A,$B,$B,$C,$C,$D,$D,$E,$E,$T,$T,$A); return($n{$p}); } sub Na { local($n)=@_; return( (($n )&0x0f), (($n+ 2)&0x0f), (($n+ 8)&0x0f), (($n+13)&0x0f), (($n+ 1)&0x0f)); } sub X_expand { local($in)=@_; &comment("First, load the words onto the stack in network byte order"); for ($i=0; $i<16; $i+=2) { &mov($A,&DWP(($i+0)*4,$in,"",0));# unless $i == 0; &mov($B,&DWP(($i+1)*4,$in,"

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值