MD5加密 MD5加盐

MD5加密 MD5加盐MD5 算法的原理可简要的叙述为 MD5 码以 512 位分组来处理输入的信息 且每一分组又被划分为 16 个 32 位子分组 经过了一系列的处理后 算法的输出由四个 32 位分组组成 将这四个 32 位分组级联后将生成一个 128 位散列值 一 为什么要用哈希函数来加密密码 1 如果开发者需要保存密码 比如网站用户的密码 要考虑如何保护这些密码数据 网站用户密码的泄露是一件非常严重的事情 容易引起

MD5算法的原理可简要的叙述为:MD5码以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

(一):为什么要用哈希函数来加密密码

    1、如果开发者需要保存密码(比如网站用户的密码),要考虑如何保护这些密码数据,网站用户密码的泄露是一件非常严重的事情,容易引起用户恐慌,所以在安全方面是重中之重,直接将密码以明文写入数据库中是极不安全的,因为任何可以打开数据库的人,都将可以直接看到这些密码。

    2、解决的办法是将密码加密后再存储进数据库,比较常用的加密方法是使用哈希函数(Hash Function)。哈希函数的具体定义,网上和相关书籍中有很多,简单地说,它的特性如下:

    (1)原始密码经哈希函数计算后得到一个哈希值;

    (2)改变原始密码,哈希函数计算出的哈希值也会相应改变;

    (3) 同样的密码,哈希值也是相同的;

    (4) 哈希函数是单向、不可逆的。也就是说从哈希值,你无法推算出原始的密码是多少;

    有了哈希函数,我们就可以将密码的哈希值存储进数据库。用户登录网站的时候,我们可以检验用户输入密码的哈希值是否与数据库中的哈希值相同。由于哈希函数是不可逆的,即使有人打开了数据库,也无法看到用户的密码是多少。

    注:但不意味着存储经过哈希函数加密后的密码就是绝对的安全!

(二):几种常见的激活成功教程密码的方法

    简单、常见的激活成功教程方式当属字典激活成功教程(Dictionary Attack)和暴力激活成功教程(Brute Force Attack)方式。

    字典激活成功教程暴力激活成功教程都是效率比较低的激活成功教程方式。如果你知道了数据库中密码的哈希值,你就可以采用一种更高效的激活成功教程方式,查表法(Lookup Tables)。还有一些方法,比如逆向查表法(Reverse Lookup Tables)、彩虹表(Rainbow Tables)等,都和查表法大同小异。现在我们来看一下查表法的原理。

    查表法不像字典激活成功教程和暴力激活成功教程那样猜密码,它首先将一些比较常用的密码的哈希值算好,然后建立一张表,当然密码越多,这张表就越大。当你知道某个密码的哈希值时,你只需要在你建立好的表中查找该哈希值,如果找到了,你就知道对应的密码了。

(三):为密码加盐(Salt

    从查表法可以看出,即便是将原始密码加密后的哈希值存储在数据库中依然是不够安全的。那么有什么好的办法来解决这个问题呢?答案是加盐值(salt)

    盐(Salt)是什么?就是一个随机生成的字符串。我们将盐与原始密码连接(concat)在一起(放在前面或后面都可以),然后将concat后的字符串加密。采用这种方式加密密码,查表法就不灵了(因为盐是随机生成的);Salt这个值是由系统随机生成的,并且只有系统知道。即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,散列值也是不同的。

 

 


Java实现

package com.md5.demo; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; / * 普通的MD加密 * @author peaceliu * */ public class MD5Utils { / * 使用md5的算法进行加密 */ public static String md5(String plainText) { byte[] secretBytes = null; try { secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes()); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("没有md5这个算法!"); } String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字 // 如果生成数字未满32位,需要前面补0 for (int i = 0; i < 32 - md5code.length(); i++) { md5code += "0"; } return md5code; } public static void main(String[] args) { System.out.println(md5("lhp")); } }

MD5加盐 

  • 一般使用的加盐:
    md5(Password+UserName),即将用户名和密码字符串相加再MD5,这样的MD5摘要基本上不可反查。
    但有时候用户名可能会发生变化,发生变化后密码即不可用了(验证密码实际上就是再次计算摘要的过程)。
    ----------






  • 因此我们做了一个非常简单的加盐算法,每次保存密码到数据库时,都生成一个随机16位数字,将这16位数字和密码相加再求MD5摘要,然后在摘要中再将这16位数字按规则掺入形成一个48位的字符串。
  • 在验证密码时再从48位字符串中按规则提取16位数字,和用户输入的密码相加再MD5。按照这种方法形成的结果肯定是不可直接反查的,且同一个密码每次保存时形成的摘要也都是不同的。
package com.md5.demo; import java.security.MessageDigest; import java.util.Random; import org.apache.commons.codec.binary.Hex; / * MD5加盐加密 */ public class PasswordUtil { / * 生成含有随机盐的密码 */ public static String generate(String password) { Random r = new Random(); StringBuilder sb = new StringBuilder(16); sb.append(r.nextInt()).append(r.nextInt()); int len = sb.length(); if (len < 16) { for (int i = 0; i < 16 - len; i++) { sb.append("0"); } } String salt = sb.toString(); password = md5Hex(password + salt); char[] cs = new char[48]; for (int i = 0; i < 48; i += 3) { cs[i] = password.charAt(i / 3 * 2); char c = salt.charAt(i / 3); cs[i + 1] = c; cs[i + 2] = password.charAt(i / 3 * 2 + 1); } return new String(cs); } / * 校验密码是否正确 */ public static boolean verify(String password, String md5) { char[] cs1 = new char[32]; char[] cs2 = new char[16]; for (int i = 0; i < 48; i += 3) { cs1[i / 3 * 2] = md5.charAt(i); cs1[i / 3 * 2 + 1] = md5.charAt(i + 2); cs2[i / 3] = md5.charAt(i + 1); } String salt = new String(cs2); return md5Hex(password + salt).equals(new String(cs1)); } / * 获取十六进制字符串形式的MD5摘要 */ public static String md5Hex(String src) { try { MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] bs = md5.digest(src.getBytes()); return new String(new Hex().encode(bs)); } catch (Exception e) { return null; } } }

测试

 public static void main(String[] args) { // 加密+加盐 String password1 = generate("admin"); System.out.println("结果:" + password1 + " 长度:"+ password1.length()); // 解码 System.out.println(verify("admin", password1)); // 加密+加盐 String password2= generate("admin"); System.out.println("结果:" + password2 + " 长度:"+ password2.length()); // 解码 System.out.println(verify("admin", password2)); }


python

md5加密

>>> import hashlib >>> >>> password = '' >>> # 生成MD5对象 >>> md5 = hashlib.md5() >>> # 对数据加密 >>> md5.update(password.encode('utf-8')) >>> # 获取密文 >>> pwd = md5.hexdigest() >>> >>> print(pwd) 25f9ebf5181f1b624d0b >>> 

md5加盐

>>> import hashlib >>> # 生成MD5对象 并加盐 >>> md5 = hashlib.md5(b'12345') >>> # 要加密的密码 >>> password = '' >>> # 对数据加密 >>> md5.update(password.encode('utf-8')) >>> # 获取密文 >>> pwd = md5.hexdigest() >>> >>> print(pwd) 1664ef4c91b2efe3b444c5139e

finally

#--------------------------------------------------- # Python3简单密码加盐程序 # 通过随机生成4位salt,与原始密码组合,通过md5加密 #--------------------------------------------------- # 导入哈希md5模块 from hashlib import md5 # 导入随机数模块 from random import Random # 获取由4位随机大小写字母、数字组成的salt值 def create_salt(length = 4): salt = '' chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0' # 获取chars的最大下标 len_chars = len(chars)-1 random = Random() for i in range(length): # 每次随机从chars中抽取一位,拼接成一个salt值 salt += chars[random.randint(0,len_chars)] return salt # 获取原始密码+salt的md5值 def create_md5(pwd,salt): md5_obj = md5() md5_obj.update((pwd+salt).encode('utf-8')) return md5_obj.hexdigest()  # 随机密码  pwd = input("请输入密码:")  # 随机生成的4位salt  salt = create_salt()  # 加密后的密码  md5_pwd = create_md5(pwd,salt)                 # 输出效果如下  请输入密码:123  密码:123  salt:DY6Z  md5加密后的密码:c18d0edce6dd6d446b9a33625

暂时先写个这样,有的话再补充。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/211119.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午11:10
下一篇 2026年3月18日 下午11:10


相关推荐

  • VS2005卸载问题「建议收藏」

    VS2005卸载问题「建议收藏」由于本人的VS2005是中英文结合的(先安装了中文版的,卸载不彻底后,又安装了英文版,造成了中英文结合的),所以在开发的时候,在遇到一些细节的时候,总是会存在编译错误,就是由于这种结合体造成的,为了净化自己的开发环境,今天决定彻底的删除这个结合体,该为英文版。重装了好几次终于成功。以下为成功步骤:先在“控制面板”的“添加删除程序中”删除所有相关…

    2026年3月3日
    4
  • 虚拟机vmware卸载不彻底的解决办法是什么_虚拟机卸载不干净

    虚拟机vmware卸载不彻底的解决办法是什么_虚拟机卸载不干净安装不成功并提示。setuphasdetectedthatvmwareworkstationisalreadyinstalledonthismachinepleaseuninstallthisproductthroughadd/removeprogramsandtryagain1.VMware无法卸载及卸载不完全解决办法…

    2022年10月20日
    8
  • Android浏览器开源项目

    Android浏览器开源项目Chrome:https://github.com/pwnallchromium_webview:https://github.com/mogoweb/chromium_webview365browser:https://github.com/mogoweb/365browserAndroidChromium:https://github.com/JackyAndroid/Androi…

    2022年5月15日
    44
  • 隐私政策

    隐私政策

    2026年3月16日
    2
  • webservice接口与HTTP接口的使用以及区别

    webservice接口与HTTP接口的使用以及区别一、webservice的概念Web是使应用程序可以与平台和编程语言无关的方式进行相互通信的一项技术。Web服务是一个软件接口,它描述了一组可以在网络上通过标准化的XML消息传递访问的操作。它使用基于XML语言的协议来描述要执行的操作或者要与另一个Web服务交换的数据。一组以这种方式交互的Web服务在面向服务的体系结构(Service-OrientedArchitectu…

    2022年5月18日
    49
  • 智谱开源GLM-OCR模型:仅0.9B参数,多项基准取得SOTA表现

    智谱开源GLM-OCR模型:仅0.9B参数,多项基准取得SOTA表现

    2026年3月12日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号