md5加密解析

2021-11-29 15:01:06 浏览数 (1)

MD5是计算机领域使用最广泛的散列函数(可以叫哈希算法、摘要算法),注意是用来确保消息的完整和一致性。 下面我们最主要是以 md5 加密为例来了解下加密算法。 MD5算法有以下特点: 1. 压缩性: 任意长度的数据,算出的MD5值长度都是固定的。 2. 容易计算:从原数据算出MD5值很容易。 3. 抗修改性:对原数据进行任何改动,哪怕只修改一个字节,所得到的MD5值都有很大的区别。 4. 强抗碰撞:已知原数据和其MD5值,想找到一个具有相同的MD5值的伪数据是非常困难的。 MD5的作用是让大容量信息在用数字签名软件签署私人秘钥前被压缩成一种保密的格式(就是把任意长度的字符串变换成一定长的十六进制数字串)。 如下使用代码:

代码语言:javascript复制
const crypto = require('crypto');

const str = 'abc';

// 创建一个hash对象
const md5 = crypto.createHash('md5');

// 往hash对象中添加摘要内容
md5.update(str);

// 使用 digest 方法输出摘要内容,不使用编码格式的参数 其输出的是一个Buffer对象
// console.log(md5.digest()); 
// 输出 <Buffer 90 01 50 98 3c d2 4f b0 d6 96 3f 7d 28 e1 7f 72>

// 使用编码格式的参数,输出的是一个字符串格式的摘要内容
console.log(md5.digest('hex')); // 输出 900150983cd24fb0d6963f7d28e17f72

Md5算法demo实列:

现在我们来看下一个demo,比如一些登录信息,比如密码直接以明文的方式存放在数据库中是不安全的,开发人员直接可以通过肉眼就可以知道,可以记下来,因此我们需要使用md5来加密一下;因此我们可以做如下代码加密:

代码语言:javascript复制
const crypto = require('crypto');

var cryptoPassFunc = function(password) {
  const md5 = crypto.createHash('md5');
  return md5.update(password).digest('hex');
};

const password = '123456';
const croptyPass = cryptoPassFunc(password);

const croptyPass2 = cryptoPassFunc(password);

console.log(croptyPass); // e10adc3949ba59abbe56e057f20f883e

console.log(croptyPass2); // e10adc3949ba59abbe56e057f20f883e

如上console.log输出的是通过md5加密后代码了;

只对md5加密的缺点:

通过上面对md5加密后确实比明文好很多,至少很多人直接使用肉眼看到的并记不住,也不知道密码多少,但是只对md5加密也存在缺点,如上代码使用console.log打印两次后,加密后的代码是一样,也就是说 相同的明文密码,加密后,输出两次,md5的值也是一样的。 所以这样也是不安全的。

密码加盐:

什么意思呢?就是在密码的特定位置上插入特定的字符串后,再对修改后的字符串进行md5加密,这样做的好处是每次调用代码的时候,插入的字符串不一样,会导致最后的md5值会不一样的。代码如下:

代码语言:javascript复制
const crypto = require('crypto');

var saltPasswordFunc = function(password, salt) {

  // 密码加盐
  const saltPassword = password   ':'   salt;
  console.log('原始密码:%s', password); 
  console.log('加盐后的密码:%s', saltPassword);


  const md5 = crypto.createHash('md5');
  const result = md5.update(saltPassword).digest('hex');
  console.log('加盐密码后的md5的值为:%s', result);

};

const password = '123456';

saltPasswordFunc(password, 'abc');
/*
 输出结果为:
 原始密码:123456
 加盐后的密码:123456:abc
 加盐密码后的md5的值为:51011af1892f59e74baf61f3d4389092
*/

saltPasswordFunc(password, 'def');
/*
 输出结果为:
 原始密码:123456
 加盐后的密码:123456:def
 加盐密码后的md5的值为:5091d17d6b08ba9a95ccef51f598b249
*/

密码加密:随机盐值

如上通过密码加盐,比单单的使用md5加密,安全性相对来说更高点,但是也存在问题,比如字符串拼接算法中的字符串开发者知道的,第二个是盐值固定,也就是说拼接的字符串的盐值是固定的;所以存在这几个问题,因此下面我们需要一个随机数来生成随机盐值。这样安全性或许会更高点。

因此优化后的代码如下:(优化点无非就是生成一个随机数当做盐值)

代码语言:javascript复制
const crypto = require('crypto');

var getRandomSalt = function() {
  // 使用六位随机数吧
  const randomSalt = Math.random().toString().slice(2, 8);
  console.log(randomSalt);
  return randomSalt;
};

var saltPasswordFunc = function(password, salt) {
  // 密码加盐
  const saltPassword = password   ':'   salt;
  console.log('原始密码:%s', password); 
  console.log('加盐后的密码:%s', saltPassword);


  const md5 = crypto.createHash('md5');
  const result = md5.update(saltPassword).digest('hex');
  console.log('加盐密码后的md5的值为:%s', result);
};

const password = '123456';

saltPasswordFunc(password, getRandomSalt());
/*
 输出结果为:
 原始密码:123456
 加盐后的密码:123456:随机生成6位数字
 加盐密码后的md5的值为:密码  ':'   随机生成6位数字 的md5值
*/

saltPasswordFunc(password, getRandomSalt());
/*
 输出结果为:
 原始密码:123456
 加盐后的密码:123456:随机生成6位数字
 加盐密码后的md5的值为:密码  ':'   随机生成6位数字 的md5值
*/

这样做的好处是:每次运行的时候,或者说叫请求的时候,盐值是不一样的,导致每次生成的md5加密后的密码是不一样的。

接下来看一下密码加盐的的实际案例:

1、安全加密:首先对数据库表的password字段进行摘要md5处理,sql语句如下:

md5加密后的数据

l 数据库密码加密后,校验的逻辑就发生了些变化,需要对提交的密码进行加密之后再做对比,但是这样子还是不安全。

(1)通过以上步骤,我们只对数据库的password明文字段进行了简单的MD5加密,进入http://www.cmd5.com/ 输入加密后的密文进行解密后可以得到明文密码

(2)容易根据密文位数推测算法,从而使用工具破解。

(3)真实密码相同,加密过的密码也相同。

2、接下来我们介绍一下对其进行加盐处理

l 在表中添加一列salt字段(盐),内容随意输入23sd2,然后和原来的明文密码123456结合,再进行md5加密

说明:所谓的salt字段就是一个随机的字段,具体随机算法就不讨论了,每当用户注册账户时,后台就给它随机生成一个不同的字段,然后根据password和salt字段结合进行摘要处理,存在数据库表中的password字段,这样一来,原来明文都是123456生成的密文就不一样了。

以上的步骤我们只是对数据库进行了加密,为了防止用户输入密码在传输的过程中被抓包工具获取,我们还要在密码传输的过程中进行加密,这样可以使得获取到的也是密文。

0 人点赞