Java实现MD5加密及解密的代码实例分享

如果对安全性的需求不是太高,MD5仍是使用非常方便和普及的加密方式,比如Java中自带的MessageDigest类就提供了支持,这里就为大家带来Java实现MD5加密及解密的代码实例分享:

 

基础:MessageDigest类的使用

其实要在Java中完成MD5加密,MessageDigest类大部分都帮你实现好了,几行代码足矣:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

/**

 * 对字符串md5加密

 *

 * @param str

 * @return

 */

import java.security.MessageDigest;

public static String getMD5(String str) {

 try {

  // 生成一个MD5加密计算摘要

  MessageDigest md = MessageDigest.getInstance("MD5");

  // 计算md5函数

  md.update(str.getBytes());

  // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符

  // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值

  return new BigInteger(1, md.digest()).toString(16);

 } catch (Exception e) {

  throw new SpeedException("MD5加密出现错误");

 }

}

 

进阶:加密及解密类
Java实现MD5加密以及解密类,附带测试类,具体见代码。

MD5加密解密类——MyMD5Util,代码如下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

package com.zyg.security.md5;

 

import java.io.UnsupportedEncodingException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.security.SecureRandom;

import java.util.Arrays;

 

public class MyMD5Util {

  

 private static final String HEX_NUMS_STR="0123456789ABCDEF";

 private static final Integer SALT_LENGTH = 12;

  

 /**

 * 将16进制字符串转换成字节数组

 * @param hex

 * @return

 */

 public static byte[] hexStringToByte(String hex) {

 int len = (hex.length() / 2);

 byte[] result = new byte[len];

 char[] hexChars = hex.toCharArray();

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

 int pos = i * 2;

 result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4

  | HEX_NUMS_STR.indexOf(hexChars[pos + 1]));

 }

 return result;

 }

 

  

 /**

 * 将指定byte数组转换成16进制字符串

 * @param b

 * @return

 */

 public static String byteToHexString(byte[] b) {

 StringBuffer hexString = new StringBuffer();

 for (int i = 0; i < b.length; i++) {

 String hex = Integer.toHexString(b[i] & 0xFF);

 if (hex.length() == 1) {

 hex = '0' + hex;

 }

 hexString.append(hex.toUpperCase());

 }

 return hexString.toString();

 }

  

 /**

 * 验证口令是否合法

 * @param password

 * @param passwordInDb

 * @return

 * @throws NoSuchAlgorithmException

 * @throws UnsupportedEncodingException

 */

 public static boolean validPassword(String password, String passwordInDb)

 throws NoSuchAlgorithmException, UnsupportedEncodingException {

 //将16进制字符串格式口令转换成字节数组

 byte[] pwdInDb = hexStringToByte(passwordInDb);

 //声明盐变量

 byte[] salt = new byte[SALT_LENGTH];

 //将盐从数据库中保存的口令字节数组中提取出来

 System.arraycopy(pwdInDb, 0, salt, 0, SALT_LENGTH);

 //创建消息摘要对象

 MessageDigest md = MessageDigest.getInstance("MD5");

 //将盐数据传入消息摘要对象

 md.update(salt);

 //将口令的数据传给消息摘要对象

 md.update(password.getBytes("UTF-8"));

 //生成输入口令的消息摘要

 byte[] digest = md.digest();

 //声明一个保存数据库中口令消息摘要的变量

 byte[] digestInDb = new byte[pwdInDb.length - SALT_LENGTH];

 //取得数据库中口令的消息摘要

 System.arraycopy(pwdInDb, SALT_LENGTH, digestInDb, 0, digestInDb.length);

 //比较根据输入口令生成的消息摘要和数据库中消息摘要是否相同

 if (Arrays.equals(digest, digestInDb)) {

 //口令正确返回口令匹配消息

 return true;

 } else {

 //口令不正确返回口令不匹配消息

 return false;

 }

 }

 

 

 /**

 * 获得加密后的16进制形式口令

 * @param password

 * @return

 * @throws NoSuchAlgorithmException

 * @throws UnsupportedEncodingException

 */

 public static String getEncryptedPwd(String password)

 throws NoSuchAlgorithmException, UnsupportedEncodingException {

 //声明加密后的口令数组变量

 byte[] pwd = null;

 //随机数生成器

 SecureRandom random = new SecureRandom();

 //声明盐数组变量

 byte[] salt = new byte[SALT_LENGTH];

 //将随机数放入盐变量中

 random.nextBytes(salt);

 

 //声明消息摘要对象

 MessageDigest md = null;

 //创建消息摘要

 md = MessageDigest.getInstance("MD5");

 //将盐数据传入消息摘要对象

 md.update(salt);

 //将口令的数据传给消息摘要对象

 md.update(password.getBytes("UTF-8"));

 //获得消息摘要的字节数组

 byte[] digest = md.digest();

 

 //因为要在口令的字节数组中存放盐,所以加上盐的字节长度

 pwd = new byte[digest.length + SALT_LENGTH];

 //将盐的字节拷贝到生成的加密口令字节数组的前12个字节,以便在验证口令时取出盐

 System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);

 //将消息摘要拷贝到加密口令字节数组从第13个字节开始的字节

 System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);

 //将字节数组格式加密后的口令转化为16进制字符串格式的口令

 return byteToHexString(pwd);

 }

}

测试类——Client,代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

package com.zyg.security.md5;

 

import java.io.UnsupportedEncodingException;

import java.security.NoSuchAlgorithmException;

import java.util.HashMap;

import java.util.Map;

 

public class Client {

 private static Map users = new HashMap();

  

 public static void main(String[] args){

 String userName = "zyg";

 String password = "123";

 registerUser(userName,password);

  

 userName = "changong";

 password = "456";

 registerUser(userName,password);

  

 String loginUserId = "zyg";

 String pwd = "1232";

 try {

  if(loginValid(loginUserId,pwd)){

  System.out.println("欢迎登陆!!!");

  }else{

  System.out.println("口令错误,请重新输入!!!");

  }

 } catch (NoSuchAlgorithmException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

 } catch (UnsupportedEncodingException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

 }

 }

  

 /**

 * 注册用户

 *

 * @param userName

 * @param password

 */

 public static void registerUser(String userName,String password){

 String encryptedPwd = null;

 try {

  encryptedPwd = MyMD5Util.getEncryptedPwd(password);

   

  users.put(userName, encryptedPwd);

   

 } catch (NoSuchAlgorithmException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

 } catch (UnsupportedEncodingException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

 }

 }

  

 /**

 * 验证登陆

 *

 * @param userName

 * @param password

 * @return

 * @throws UnsupportedEncodingException

 * @throws NoSuchAlgorithmException

 */

 public static boolean loginValid(String userName,String password)

  throws NoSuchAlgorithmException, UnsupportedEncodingException{

 String pwdInDb = (String)users.get(userName);

 if(null!=pwdInDb){ // 该用户存在

  return MyMD5Util.validPassword(password, pwdInDb);

 }else{

  System.out.println("不存在该用户!!!");

  return false;

 }

 }

}

转载于:https://my.oschina.net/u/2542649/blog/793746

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值