密码和Java中的加解密之MD5加点盐
很多人都用MD5+Base64方式存储密码,这种存储方式 方便、速度快而且由于MD5杂凑算法的几乎不可还原性,攻击者只能通过"猜"去破解密码。
但是MD5对相同的数据返回的信息永远是一样的,"123456"通过MD5+Base64编码后,永远是"4QrcOUm6Wau+VuBX8g+IPg==",攻击者只需要一个简单的sql语句:select * from userInfo where password='4QrcOUm6Wau+VuBX8g+IPg==' 就可以知道有几个用户密码是"123456",这对一个项目来说十分危险。
//这个循环无论执行几次,返回都是一样。static void t3(){for(int i=0;i<5;i++){try {String inputPwd = "123456";MessageDigest md;BASE64Encoder b64Encoder = new BASE64Encoder();byte[] bys = null;md = MessageDigest.getInstance("MD5","SUN");md.reset();md.update(inputPwd.getBytes("UTF-8"));bys = md.digest();System.out.println("编码后:"+b64Encoder.encode(bys)); } catch (Exception e) {e.printStackTrace();}}}
一种简单有效的解决方法,就是在MD5杂凑前加点随机码,这样攻击者将无法通过一个简单的SQL语句来查找密码是"123456"的用户。
随机码长度是应该固定,且同用户输入的密码一起进行MD5杂凑,随机码应该在Base64编码后的固定位置。
校验时,先取出随机码,再同输入一起进行MD5杂凑,与以前存储的密码比较是否一致。
package test1;import java.security.MessageDigest;
import java.util.Random;import sun.misc.BASE64Encoder;/*** 对帐号口令加密* @author shanl**/
public class PasswdEncryption {private static final MessageDigest md;private static final BASE64Encoder b64Encoder;static{try {md = MessageDigest.getInstance("MD5", "SUN");b64Encoder = new BASE64Encoder();} catch (Exception e) {throw new RuntimeException(e);}}/*** 检查密码* @param inputPasswd 用户输入的密码* @param storePasswd 已存储的密码* @return true:通过检查,false:未通过*/synchronizedpublic static boolean checkPasswd(String inputPasswd, String storePasswd){boolean ok = false;try{byte[] saltBys = storePasswd.substring(0,2).getBytes("UTF-8");String inPwd = toPasswd(inputPasswd, saltBys);ok = inPwd.equals(storePasswd);}catch(Exception ex){ex.printStackTrace();ok = false;}return ok;}/*** 将客户输入的密码加密* @param inputPasswd* @return*/synchronized public static String toPasswd(String inputPasswd){byte[] salt = getSaltOfASCII(2);return toPasswd(inputPasswd, salt);}/*** 将客户输入的密码加密* @param inputPasswd 客户输入的密码 * @param salt 盐* @return 加密后的字符串*/synchronizedprivate static String toPasswd(String inputPasswd, byte[] salt){String pwd = "";try{ md.reset();md.update(salt);md.update(inputPasswd.getBytes("UTF-8"));byte[] bys = md.digest();;//1:AASLexNtFtI7e1IuQIg88ZNA==//879:AA/lCM5NEwVQJ25YYomE1ldQ==//1000:AARXKQat7z+/iu2w6KpKgLQA==
// for(int i=0; i<1000; i++){
// md.reset();
// bys = md.digest(bys);
// }pwd += (char)salt[0];pwd += (char)salt[1];pwd += b64Encoder.encode(bys); }catch(Exception ex){ex.printStackTrace();pwd = "";}return pwd;}/*** 返回指定长度的盐(ASCII码)* @param len 长度* @return*/private static byte[] getSaltOfASCII(int len){byte[] salt = new byte[len];Random rand = new Random();for(int i=0; i<len; i++){
// salt[i] = 'A';salt[i] = (byte) ((rand.nextInt('~'-'!')+'!') & 0x007f);}return salt;}
}
测试类:
package test1;public class Test8 {public static void main(String[] args){t2();
// t1();}static void t2(){String[] userPwds = {"123456","123456","123456","123456","123456","1234561", //error input};//通过t1()得到String[] dbPwds = {"u:rkoqEBZ+IZlcugSyVkhNVg==","vDEbVZ9JlSveGnB/Qdz69aAQ==","hbgon/TjwH8s7YSuqVSDl9Yg==","0-ExML8oTOSCeF3ETf1yvDHg==","1TeHpWiXOhx5ilscC6D6G98g==","1TeHpWiXOhx5ilscC6D6G98g==",};String msg = "";for(int i=0,end=dbPwds.length; i<end; i++){msg = "user input passwd:"+userPwds[i];msg += ",db store passwd:"+dbPwds[i];msg += ",check passwd:"+PasswdEncryption.checkPasswd(userPwds[i],dbPwds[i]);System.out.println(msg);}}/*** 加密测试*/static void t1(){String pwd = "123456";String pwd1 = null;//PasswdEncryption.toPasswd(pwd);for(int i=0; i<5; i++){pwd1 = PasswdEncryption.toPasswd(pwd);System.out.println(pwd1);}}
}
t1()结果显示,在很小的情况下会出现相同的加密后密码,攻击者很难用一个简单SQL去查找同一密码的用户。
t2()则可以用同一个密码"123456"验证,多个加密后的密码。
密码和Java中的加解密之MD5加点盐相关推荐
- Java使用AES加解密
Java使用AES加解密 目录 1.1生成密钥 1.2密钥的存储 1.3获取存储的密钥 1.4加解密 1.5使用存储的密钥进行加解密示例 AES是一种对称的加密算法,可基于相同的密钥进行加密和解密.J ...
- java实现DES加解密算法
以下是我用java实现的DES算法,实现中可能存在一点问题自己没空去找,但我觉得DES的算法过程肯定没错!现在暂时没时间去找到底是哪里的问题,有空再瞧瞧自己的代码喽! makekey.java是生成密 ...
- 一个java的DES加解密类转换成C#
原文:一个java的DES加解密类转换成C# 一个java的des加密解密代码如下: //package com.visionsky.util;import java.security.*; //im ...
- JAVA:实现XXTea加解密算法(附完整源码)
JAVA:实现XXTea加解密算法 public class XXTEAprivate XXTEA() {}public static byte[] encrypt(byte[] data, byte
- Java中动态加载字节码的方法 (持续补充)
文章目录 Java中动态加载字节码的方法 1.利用 URLClassLoader 加载远程class文件 2.利用 ClassLoader#defineClass 直接加载字节码 2.1 类加载 - ...
- 【AES256】Java实现AES256加解密
AES256加解密比较常见,这里简单记录以供参考! 一.下载 官方JDK默认支持AES-128,在 1.8.0_151 和 1.8.0_152 版本之前,需要从Oracle官网下载安全JAR包方可支持 ...
- Java 进行 RSA 加解密时不得不考虑到的那些事儿
1. 加密的系统不要具备解密的功能,否则 RSA 可能不太合适 公钥加密,私钥解密.加密的系统和解密的系统分开部署,加密的系统不应该同时具备解密的功能,这样即使黑客攻破了加密系统,他拿到的也只是一堆无 ...
- openssl c++实现bouncycastle中AES加解密
0x01 为什么要用bouncycastle 先说说JCE(Java Cryptography Extension)是一组包,它们提供用于加密.密钥生成和协商以及 Message Authentica ...
- Java中3DES加密解密示例
在java中调用sun公司提供的3DES加密解密算法时,需要使用到$JAVA_HOME/jre/lib/目录下如下的4个jar包: jce.jar security/US_export_policy. ...
最新文章
- 基于ASP.Net Core开发的一套通用后台框架
- git把本地代码上传(更新)到github上
- 在阿里淘系6个月能有哪些收获成长?
- 旅游系统_旅游标识系统,必须真的“旅游化”
- 前端复习之JavaScript基础
- matlab程序中中零内插在qdpsk调制中的作用,桂林电子科技大学通信原理思考题
- Linux 内核调试指南[转载]
- 【scratch音乐课】天空之城:音符与节拍、消息与链表
- 【Android工具】更新手机流媒体播放器,手机DLNA播放器OPlayer
- 四柱八字大全 php,四柱八字
- WEB安全(十六)单点登录的基本实现
- 安卓zip解压软件_手机压缩软件ZArchiver下载、使用教程丨免费、中文,支持7z、zip、rar等所有格式...
- 将iTunes降级到12.6版本
- 【pycharm】英文输入法变成全角字符无法输入
- 探究 | Elasticsearch如何物理删除给定期限的历史数据?
- 实现微信小程序web-view内嵌H5中的下载功能(大文件切片下载)
- 消灭泡泡糖游戏java编程_JAVA面向对象编程课程设计——泡泡堂
- w7计算机防火墙无法更改,w7防火墙无法更改该怎么办
- 西电硕士论文 Latex 模板:填坑!
- 登录界面及其功能的设计
热门文章
- ### Cause: java.sql.SQLSyntaxErrorException: ORA-00903: 表名无效
- 删除数组最后一个元素
- 秦羽接引的鸿蒙第四人,星辰变:仙界最强的五人,秦羽第二,敖无虚垫底,小黑难进前三...
- obs源码二次开发,自定义插入SEI
- 计算机学院陈宇,计算机学院学生社团联合会第一次全体会议顺利召开
- JavaScript小技能:客户端 API
- Java三个月速成学习路线图
- 3d游戏建模可以自学吗?小白教程
- if和for的几个经典题目
- 史上最详细的maven仓库详解