在实际项目中,为了安全性考虑,常常要求帐号密码是以加密后的密文形式,保存到数据库中。html
这样,即便有人获取到了数据库中的密文密码,也不知道明文密码信息是什么,从而防止系统被恶意访问。前端
密码加密有不少种方式,好比:Base64,DSA,RSA,MD5,SHA128,SHA256,SHA512等加密方式。java
本文主要讲述 MD5 加密方式。算法
MD5 消息摘要算法(英文:MD5 Message-Digest Algorithm),一种被普遍使用的密码散列函数,能够产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。数据库
MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。apache
利用它的单向加密性,即不可逆性,咱们能够应用于数据和密码的加密。json
因为MD5算法的单向性,由MD5码计算出原文几乎是不可能的。目前对于这种加密方法的破解方式是收集经常使用的密码形式,例如生日,身份证号,电话号码等。把这些收集到的秘密用MD5处理以后进行存储,而后与须要还原的MD5进行比对,当收集的数据达到必定的数目,用户密码被破解的可能性就会变得很大。后端
对于这种方法,一种增强安全性的方法就是在对用户密码进行MD5处理的时候在原密码上加一个附近值,例如原密码为“password”,处理的时候变为“passworddrowssap”,通过这样的处理以后能够有效下降密码被破解的可能性。数组
每一个文件均可以计算出一个特定的 MD5 值。安全
好比,咱们上传一个文件到服务器上,能够同时计算出该文件对应的 MD5 值;
在文件下载的时候,经过再次计算该文件的 MD5 值。
若是两个MD5值相同,说明文件没有变化,不然,说明文件被修改过。
经过Java编写程序,实现对任意字符串进行 MD5 加密。
代码以下:
package com.miracle.luna.md5; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * Created by Miracle Luna on 2019/11/18 */ public class Md5UtilOriginal { /** * 将数据进行 MD5 加密,并以16进制字符串格式输出 * @param data * @return */ public static String md5(String data) { try { byte[] md5 = md5(data.getBytes("utf-8")); return toHexString(md5); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ""; } /** * 将字节数组进行 MD5 加密 * @param data * @return */ public static byte[] md5(byte[] data) { try { MessageDigest md = MessageDigest.getInstance("md5"); return md.digest(data); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return new byte[]{}; } /** * 将加密后的字节数组,转换成16进制的字符串 * @param md5 * @return */ private static String toHexString(byte[] md5) { StringBuilder sb = new StringBuilder(); System.out.println("md5.length: " + md5.length); for (byte b : md5) { sb.append(Integer.toHexString(b & 0xff)); } return sb.toString(); } public static void main(String[] args) { String password = "password"; String md5HexStr = md5(password); System.out.println("==> MD5 加密前: " + password); System.out.println("==> MD5 加密后: " + md5HexStr); } }
运行结果以下:
md5.length: 16
==> MD5 加密前: password ==> MD5 加密后: 5f4dcc3b5aa765d61d8327deb882cf99
代码以下:
package com.miracle.luna.md5; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * Created by Miracle Luna on 2019/11/18 */ public class Md5UtilSimple { /** * 将数据进行 MD5 加密,并以16进制字符串格式输出 * @param data * @return */ public static String md5(String data) { StringBuilder sb = new StringBuilder(); try { MessageDigest md = MessageDigest.getInstance("md5"); byte[] md5 = md.digest(data.getBytes(StandardCharsets.UTF_8)); // 将字节数据转换为十六进制 for (byte b : md5) { sb.append(Integer.toHexString(b & 0xff)); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return sb.toString(); } public static void main(String[] args) { String password = "password"; String md5HexStr = md5(password); System.out.println("==> MD5 加密前: " + password); System.out.println("==> MD5 加密后: " + md5HexStr); } }
运行结果以下:
==> MD5 加密前: password ==> MD5 加密后: 5f4dcc3b5aa765d61d8327deb882cf99
代码以下:
package com.miracle.luna.md5; // 此处须要引入 commons-codec-1.13.jar import org.apache.commons.codec.binary.Hex; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * Created by Miracle Luna on 2019/11/18 */ public class Md5Util { /** * 将数据进行 MD5 加密,并以16进制字符串格式输出 * @param data * @return */ public static String md5(String data) { try { MessageDigest md = MessageDigest.getInstance("MD5"); return Hex.encodeHexString(md.digest(data.getBytes(StandardCharsets.UTF_8))); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } public static void main(String[] args) { String password = "password"; String md5HexStr = md5(password); System.out.println("==> MD5 加密前: " + password); System.out.println("==> MD5 加密后: " + md5HexStr); } }
运行结果以下:
==> MD5 加密前: password ==> MD5 加密后: 5f4dcc3b5aa765d61d8327deb882cf99
commons-codec-1.13.jar 的 pom 引用以下:
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.13</version> </dependency>
http://www.bejson.com/enc/md5/ (不只支持 MD5加密,还支持 Base64,SHA等)
效果以下(在“加密前”后的输入框中输入须要 MD5 加密的字符串 --> 点击“MD5加密” --> 便可在“加密后”的显示显示框中看到加密后的密文):
效果以下(输入框中输入须要解密的 MD5 密文,点击解密便可解密 ):
2) https://www.cmd5.com/ (这是一款很强大的解密工具,不只支持 MD5,还支持SHA的解密)
效果以下(在密文输入框中输入 MD5 密文,点击“解密”,便可看到 MD5 的明文):
解密种类众多,选择范围以下:
因为如今直接将密码用 MD5 算法加密存在必定的安全隐患(被暴力破解的可能性),咱们能够根据实际的须要,对密码加密的过程作一些逻辑处理。
好比,以下逻辑处理:
1)password --> Base64 加密,获得加密后的密码A;
2)password --> 翻转获得drowssap --> MD5 加密,获得加密后的密码B;
3)密码A+密码B拼接 --> MD5 加密,获得加密后的密码C;
4)密码C --> 翻转操做,产生密码D,做为最终的密文密码存到数据库中。
这样能够加强密码的安全性,减小被破解的可能性。(此处具体的逻辑优化,能够根据我的喜爱和实际需求,灵活定义其变换的复杂性)。
当密码以 MD5 密文存入到数据库中,用户登陆的时候,前端将用户输入的明文密码传输给后端。
后端程序用一样的处理逻辑对其进行 MD5 加密,用加密后的密码与数据库中该用户的密文密码比较。
若是两者相等,说明用户输入的密码正确,容许访问系统;不然,说明密码不正确,禁止访问。
另外,为了系统的安全性考虑,防止恶意暴力尝试破解密码,咱们常常限制用户输入密码错误的次数。
好比,连续输入3次或者5次密码,将会自动锁定帐号一段时间(根据实际场景,设置锁定时长)。
关于 Base64 加密&解密 的Java 语言实现,请参考博客:http://www.javashuo.com/article/p-bzbracey-bv.html
但愿能帮到你们,谢谢!