mysql 解密JAVA 用desdes文件加密解密数据

使用 Salt + Hash 将密码加密后再存储进数据库
转载 &更新时间:日 08:54:34 & 作者:
如果你需要保存密码(比如网站用户的密码),你要考虑如何保护这些密码数据,象下面那样直接将密码写入数据库中是极不安全的,因为任何可以打开数据库的人,都将可以直接看到这些密码
(一) 为什么要用哈希函数来加密密码
如果你需要保存密码(比如网站用户的密码),你要考虑如何保护这些密码数据,象下面那样直接将密码写入数据库中是极不安全的,因为任何可以打开数据库的人,都将可以直接看到这些密码。
解决的办法是将密码加密后再存储进数据库,比较常用的加密方法是使用哈希函数(Hash Function)。哈希函数的具体定义,大家可以在网上或者相关书籍中查阅到,简单地说,它的特性如下:
(1)原始密码经哈希函数计算后得到一个哈希值
(2)改变原始密码,哈希函数计算出的哈希值也会相应改变
(3) 同样的密码,哈希值也是相同的
(4) 哈希函数是单向、不可逆的。也就是说从哈希值,你无法推算出原始的密码是多少
有了哈希函数,我们就可以将密码的哈希值存储进数据库。用户登录网站的时候,我们可以检验用户输入密码的哈希值是否与数据库中的哈希值相同。
由于哈希函数是不可逆的,即使有人打开了数据库,也无法看到用户的密码是多少。
那么存储经过哈希函数加密后的密码是否就是安全的了呢?我们先来看一下几种常见的破解密码的方法。
(二) 几种常见的破解密码的方法
最简单、常见的破解方式当属字典破解(Dictionary Attack)和暴力破解(Brute Force Attack)方式。这两种方法说白了就是猜密码。
字典破解和暴力破解都是效率比较低的破解方式。如果你知道了数据库中密码的哈希值,你就可以采用一种更高效的破解方式,查表法(Lookup Tables)。还有一些方法,比如逆向查表法(Reverse Lookup Tables)、彩虹表(Rainbow Tables)等,都和查表法大同小异。现在我们来看一下查表法的原理。
查表法不像字典破解和暴力破解那样猜密码,它首先将一些比较常用的密码的哈希值算好,然后建立一张表,当然密码越多,这张表就越大。当你知道某个密码的哈希值时,你只需要在你建立好的表中查找该哈希值,如果找到了,你就知道对应的密码了。
(三) 为密码加盐(Salt)
从上面的查表法可以看出,即便是将原始密码加密后的哈希值存储在数据库中依然是不够安全的。那么有什么好的办法来解决这个问题呢?答案是加盐。
盐(Salt)是什么?就是一个随机生成的字符串。我们将盐与原始密码连接(concat)在一起(放在前面或后面都可以),然后将concat后的字符串加密。采用这种方式加密密码,查表法就不灵了(因为盐是随机生成的)。
(四) 在.NET中的实现
在.NET中,生成盐可以使用RNGCryptoServiceProvider类,当然也可以使用GUID。哈希函数的算法我们可以使用SHA(Secure Hash Algorithm)家族算法,当然哈希函数的算法有很多,比如你也可以采用MD5。这里顺便提一下,美国政府以前广泛采用SHA-1算法,在2005年被我国山东大学的王小云教授发现了安全漏洞,所以现在比较常用SHA-1加长的变种,比如SHA-256。在.NET中,可以使用SHA256Managed类。
下面来看一段代码演示如何在.NET中实现给密码加盐加密。加密后的密码保存在MySQL数据库中。
下面的代码演示如何注册一个新帐户。盐的生成可以使用新Guid,也可以使用RNGCryptoServiceProvider 类。将byte[]转换为string,可以使用Base64String(我在以前的博客中介绍过Base 64 Encoding 编码),也可以使用下面的ToHexString方法。 代码如下:protected void ButtonRegister_Click(object sender, EventArgs e) { &&& string username = TextBoxUserName.T &&& string password = TextBoxPassword.T &&& // random salt &&& string salt = Guid.NewGuid().ToString();
&&& // random salt &&& // you can also use RNGCryptoServiceProvider class&&&&&&&&&&& &&& //System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider(); &&& //byte[] saltBytes = new byte[36]; &&& //rng.GetBytes(saltBytes); &&& //string salt = Convert.ToBase64String(saltBytes); &&& //string salt = ToHexString(saltBytes); &&& byte[] passwordAndSaltBytes = System.Text.Encoding.UTF8.GetBytes(password + salt);&&&&&&&&&&& &&& byte[] hashBytes = new System.Security.Cryptography.SHA256Managed().ComputeHash(passwordAndSaltBytes);
&&& string hashString = Convert.ToBase64String(hashBytes);
&&& // you can also use ToHexString to convert byte[] to string &&& //string hashString = ToHexString(hashBytes); &&& var db = new TestEntities(); &&& usercredential newRecord = usercredential.Createusercredential(username, hashString, salt); &&& db.usercredentials.AddObject(newRecord); &&& db.SaveChanges(); }
string ToHexString(byte[] bytes) { &&& var hex = new StringBuilder(); &&& foreach (byte b in bytes) &&& { &&&&&&& hex.AppendFormat("{0:x2}", b); &&& } &&& return hex.ToString(); }
下面的代码演示了如何检验登录用户的密码是否正确。首先检验用户名是否存在,如果存在,获得该用户的盐,然后用该盐和用户输入的密码来计算哈希值,并和数据库中的哈希值进行比较。 代码如下:protected void ButtonSignIn_Click(object sender, EventArgs e) { string username = TextBoxUserName.T string password = TextBoxPassword.T var db = new TestEntities(); usercredential record = db.usercredentials.Where(x =& string.Compare(x.UserName, username, true) == 0).FirstOrDefault(); if (record == default(usercredential)) { throw new ApplicationException("invalid user name and password"); } string salt = record.S byte[] passwordAndSaltBytes = System.Text.Encoding.UTF8.GetBytes(password + salt); byte[] hashBytes = new System.Security.Cryptography.SHA256Managed().ComputeHash(passwordAndSaltBytes); string hashString = Convert.ToBase64String(hashBytes); if (hashString == record.PasswordHash) { // user login successfully } else { throw new ApplicationException("invalid user name and password"); } }总结:单单使用哈希函数来为密码加密是不够的,需要为密码加盐来提高安全性,盐的长度不能过短,并且盐的产生应该是随机的。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具博客分类:
package cn.lry.iteye.jpa.
import java.io.F
import java.io.FileW
import java.io.IOE
import java.io.PrintW
import java.sql.C
import java.sql.DatabaseMetaD
import java.sql.DriverM
import java.sql.PreparedS
import java.sql.ResultS
import java.sql.ResultSetMetaD
import java.sql.SQLE
import java.util.ArrayL
import java.util.D
import java.util.L
* 从数据库表反射出实体类,自动生成实体类
* @author lry
public class GenEntityMysql {
private String packageOutPath = "cn.lry.iteye.jpa.po";//指定实体生成所在包的路径
private String authorName = "lry";//作者名字
private String tablename = "";//表名
private String[] // 列名数组
private String[] colT //列名类型数组
private int[] colS //列名大小数组
private boolean f_util = // 是否需要导入包java.util.*
private boolean f_sql = // 是否需要导入包java.sql.*
private boolean f_jpa = // 是否需要生成基于注解的JPA实体对象
//数据库连接
private static final String URL ="jdbc:mysql://localhost:3306/yu120";
private static final String NAME = "root";
private static final String PASS = "123456";
private static final String DRIVER ="com.mysql.jdbc.Driver";
* 构造函数
public GenEntityMysql(){
List&String& list=getTableName();
for(int p=0;p&list.size();p++){
tablename=list.get(p);
//创建连接
//查要生成实体类的表
String sql = "select * from " +
PreparedStatement pStemt =
Class.forName(DRIVER);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
con = DriverManager.getConnection(URL,NAME,PASS);
pStemt = con.prepareStatement(sql);
ResultSetMetaData rsmd = pStemt.getMetaData();
int size = rsmd.getColumnCount(); //统计列
colnames = new String[size];
colTypes = new String[size];
colSizes = new int[size];
for (int i = 0; i & i++) {
colnames[i] = rsmd.getColumnName(i + 1);
colTypes[i] = rsmd.getColumnTypeName(i + 1);
if(colTypes[i].equalsIgnoreCase("datetime")){
if(colTypes[i].equalsIgnoreCase("image") || colTypes[i].equalsIgnoreCase("text")){
colSizes[i] = rsmd.getColumnDisplaySize(i + 1);
String content = parse(colnames,colTypes,colSizes);
File directory = new File("");
String outputPath = directory.getAbsolutePath()+ "/src/"+this.packageOutPath.replace(".", "/")+"/"+initcap(tablename) + ".java";
FileWriter fw = new FileWriter(outputPath);
PrintWriter pw = new PrintWriter(fw);
pw.println(content);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally{
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("生成完毕!");
* Java方法 得到当前数据库下所有的表名
* @param con
private List&String& getTableName() {
List&String& list=new ArrayList&String&();
DatabaseMetaData meta = DriverManager.getConnection(URL,NAME,PASS).getMetaData();
ResultSet rs = meta.getTables(null, null, null,new String[]{"TABLE"});
while (rs.next()) {
list.add(rs.getString(3));
}catch(Exception e){
e.printStackTrace();
* 功能:生成实体类主体代码
* @param colnames
* @param colTypes
* @param colSizes
private String parse(String[] colnames, String[] colTypes, int[] colSizes) {
StringBuffer sb = new StringBuffer();
sb.append("package " + this.packageOutPath + ";\r\n");
sb.append("\r\n");
//判断是否导入工具包
if(f_util){
sb.append("import java.util.D\r\n");
if(f_sql){
sb.append("import java.sql.*;\r\n");
if(f_jpa){
sb.append("import javax.persistence.E\r\n");
sb.append("import javax.persistence.GeneratedV\r\n");
sb.append("import javax.persistence.GenerationT\r\n");
sb.append("import javax.persistence.Id;\r\n\r\n");
//注释部分
sb.append("/**\r\n");
sb.append(" * "+tablename+" 实体类\r\n");
sb.append(" * "+new Date()+"\r\n");
sb.append(" * @"+this.authorName+"\r\n");
sb.append(" */ \r\n");
if(f_jpa){
sb.append("@Entity\r\n");
//实体部分
sb.append("public class " + initcap(tablename) + "{\r\n\r\n");
processAllAttrs(sb);//属性
processAllMethod(sb);//get set方法
sb.append("}\r\n");
//System.out.println(sb.toString());
return sb.toString();
* 功能:生成所有属性
* @param sb
private void processAllAttrs(StringBuffer sb) {
for (int i = 0; i & colnames. i++) {
sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + colnames[i] + ";\r\n");
sb.append("\r\n");
* 功能:生成所有方法
* @param sb
private void processAllMethod(StringBuffer sb) {
for (int i = 0; i & colnames. i++) {
if(f_jpa){
sb.append("\t@Id\r\n");
sb.append("\t@GeneratedValue(strategy = GenerationType.AUTO)\r\n");
sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + initcap(colnames[i]) + "(){\r\n");
sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + initcap(colnames[i]) + "(){\r\n");
sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + initcap(colnames[i]) + "(){\r\n");
sb.append("\t\treturn " + colnames[i] + ";\r\n");
sb.append("\t}\r\n\r\n");
sb.append("\tpublic void set" + initcap(colnames[i]) + "(" + sqlType2JavaType(colTypes[i]) + " " + colnames[i] + "){\r\n");
sb.append("\t\tthis." + colnames[i] + "=" + colnames[i] + ";\r\n");
sb.append("\t}\r\n\r\n");
* 功能:将输入字符串的首字母改成大写
* @param str
private String initcap(String str) {
char[] ch = str.toCharArray();
if(ch[0] &= 'a' && ch[0] &= 'z'){
ch[0] = (char)(ch[0] - 32);
return new String(ch);
* 功能:获得列的数据类型
* @param sqlType
private String sqlType2JavaType(String sqlType) {
if(sqlType.equalsIgnoreCase("bit")){
return "boolean";
}else if(sqlType.equalsIgnoreCase("tinyint")){
return "byte";
}else if(sqlType.equalsIgnoreCase("smallint")){
return "short";
}else if(sqlType.equalsIgnoreCase("int")||sqlType.equalsIgnoreCase("INT UNSIGNED")){
//INT UNSIGNED无符号整形
return "int";
}else if(sqlType.equalsIgnoreCase("bigint")){
return "long";
}else if(sqlType.equalsIgnoreCase("float")){
return "float";
}else if(sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("numeric")
|| sqlType.equalsIgnoreCase("real") || sqlType.equalsIgnoreCase("money")
|| sqlType.equalsIgnoreCase("smallmoney")){
return "double";
}else if(sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("char")
|| sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nchar")
|| sqlType.equalsIgnoreCase("text")){
return "String";
}else if(sqlType.equalsIgnoreCase("datetime")){
return "Date";
}else if(sqlType.equalsIgnoreCase("image")){
return "Blod";
* @param args
public static void main(String[] args) {
new GenEntityMysql();
浏览: 48081 次
尽量不设置@Property、@Embed、@EmbedLis ...
有分组查询么?
这个or方法怎么用啊,试了一下好像是当and查询一样比如我要查 ...
在maven (http://search.maven.org ...
我用bugu-mongo-1.14时都有,你用的两个版本应该也 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'博客分类:
一般spring容器启动时,通过PropertyPlaceholderConfigurer类读取jdbc.properties文件里的数据库配置信息。
通过这个原理,我们把加密后的数据库配置信息放到jdbc.properties文件里,然后自定义一个继承PropertyPlaceholderConfigurer的类,实现解密,把解密后的信息又放回去。最后在配置DataSource时,还是用占位符${}取配置信息。
jdbc.properties文件内容:
jdbc.driverClassName = 4A490AA9B8CD7DBD61E000CD76AA507B9
jdbc.url = FA0DD23D31BCF4CCBDE9CF7D1E05FBFA29BC54A
jdbc.username = 5DE376A5FF13A1D5AFD452
jdbc.password = 5DE376A5FF13A1D5AFD452
自定义的取加密信息的类EncryptablePropertyPlaceholderConfigurer
public class EncryptablePropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private static final String key = "0002";
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props)
throws BeansException {
Des des = new Des();
String username = props.getProperty("jdbc.username");
if (username != null) {
props.setProperty("jdbc.username", des.Decrypt(username, des.hex2byte(key)));
String password = props.getProperty("jdbc.password");
if (password != null) {
props.setProperty("jdbc.password", des.Decrypt(password, des.hex2byte(key)));
String url = props.getProperty("jdbc.url");
if (url != null) {
props.setProperty("jdbc.url", des.Decrypt(url, des.hex2byte(key)));
String driverClassName = props.getProperty("jdbc.driverClassName");
if(driverClassName != null){
props.setProperty("jdbc.driverClassName", des.Decrypt(driverClassName, des.hex2byte(key)));
super.processProperties(beanFactory, props);
} catch (Exception e) {
e.printStackTrace();
throw new BeanInitializationException(e.getMessage());
Des.java是一个用Des算法加密和解密的工具类
public static String Encrypt(String str, byte[] key){
Security.addProvider(new com.sun.crypto.provider.SunJCE());
byte[] encrypt = encryptMode(key, str.getBytes());
return byte2hex(encrypt);
public static String Decrypt(String str, byte[] key){
Security.addProvider(new com.sun.crypto.provider.SunJCE());
byte[] decrypt = decryptMode(key, hex2byte(str));
return new String(decrypt);
spring配置:
&bean id="propertyConfigurer"
class="com.eeds.core.security.datasource.EncryptablePropertyPlaceholderConfigurer"&
&property name="locations"&
&value&classpath:config/spring/jdbc-test.properties&/value&
&/property&
&!-- 测试环境 --&
&bean id="econsoleDS" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"&
&property name="driverClass"&
&value&${jdbc.driverClassName}&/value&
&/property&
&property name="jdbcUrl"&
&value&${jdbc.url}&/value&
&/property&
&property name="user"&
&value&${jdbc.username}&/value&
&/property&
&property name="password"&
&value&${jdbc.password}&/value&
&/property&
参考资料:
Spring配置密码加密
下载次数: 449
浏览 15419
浏览: 485817 次
来自: 上海
请问这样做的意义何在?
学习了哦!!!
学习了,感谢分享
哥们,给了思路,赞一个。
public static boolean isVa ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'Java、JavaScript、Oracle、MySQL中实现的MD5加密算法分享
转载 &更新时间:日 10:14:35 & 投稿:junjie
这篇文章主要介绍了Java、JavaScript、Oracle、MySQL中实现的MD5加密算法分享,需要的朋友可以参考下
MD5,全称为 Message Digest Algorithm 5(消息摘要算法第五版).详情请参考
MD5加密后是一个字节数组, 但我们一般是取其十六进制的字符串表示法,当然,十六进制数字符串是区分大小写,在 mysql数据库,Java,和JavaScript语言中,一般是使用小写的字符串来表示, 而在 Oracle数据库官方提供的包中,返回的是大写字符串,这算是一个坑,如果你想要执行多次 md5,可能需要转换为小写.
相关的代码如下:
1. Java版MD5
MD5Util.java
package com.cncounter.util.
import java.security.MessageD
import java.security.NoSuchAlgorithmE
* Java消息摘要算法 MD5 工具类,其实其他摘要算法的实现也类似
public class MD5Util {
* 对文本执行 md5 摘要加密, 此算法与 mysql,JavaScript生成的md5摘要进行过一致性对比.
* @param plainText
* @return 返回值中的字母为小写
public static String md5(String plainText) {
if (null == plainText) {
plainText = "";
String MD5Str = "";
// JDK 6 支持以下6种消息摘要算法,不区分大小写
// md5,sha(sha-1),md2,sha-256,sha-384,sha-512
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
StringBuilder builder = new StringBuilder(32);
for (int offset = 0; offset & b. offset++) {
i = b[offset];
if (i & 0)
if (i & 16)
builder.append("0");
builder.append(Integer.toHexString(i));
MD5Str = builder.toString();
// LogUtil.println("result: " + buf.toString());// 32位的加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return MD5S
// 一个简版测试
public static void main(String[] args) {
String m1 = md5("1");
String m2 = md5(m1);
* m1=c4ca820dcc509a6f75849b
* m2=28c8edde3d61ab
System.out.println("m1="+m1);
System.out.println("m2="+m2);
2. MySQL版MD5
MySQL直接支持 md5函数调用
select md5('1') as m1, md5(md5('1')) as m2;
执行结果为:
MariaDB [(none)]& select md5('1') as m1, md5(md5('1')) as m2;
+----------------------------------+----------------------------------+
+----------------------------------+----------------------------------+
| c4ca820dcc509a6f75849b | 28c8edde3d61ab |
+----------------------------------+----------------------------------+
1 row in set (0.00 sec)
3. JavaScript 版MD5函数
md5.js 代码如下:
/*! JavaScript 的 MD5 实现 */
// 括号表达式, (xxxxx) 是用来将内部的语句、表达式的结果作为一个结果.
// 常见的是将json字符串用 eval 解析时,需要 eval("(" +jsonstr+ ")");
// () 内部定义了一个空间, 里面定义的变量不会污染到全局空间,很适合做lib
// (function UMD(对象/函数名name, 上下文this, 函数/对象的定义)) 返回一个匿名函数
// 因为第一个括号内 的结果是一个函数,而函数可以这样调用: (function(形参){})(实参);
// 这种匿名函数被浏览器解析后会自动执行一次.
(function UMD(name, context, definition) {
if ( typeof module !== "undefined" && module.exports) {
// 如果 module 存在,并且module.exports存在,则将赋值结果赋给 它
// 可以不用管
module.exports = definition();
} else if ( typeof define === "function" && define.amd) {
// 如果 define 这个函数存在,应该是另一个基础类库,则使用define
// 可以不用管
define(definition);
// 简单一点,可以看成: 调用传入的definition函数,将返回的对象绑定到全局空间
// 当然,根据传入的上下文不同,也可以绑定到其他对象下面,成为一个属性方法.
context[name] = definition(name, context);
)("md5", this, function DEF(name, context) {"use strict";
// 上面的 use strict 表示严格语法模式,有错误就拒绝执行.
// 而普通的JS,是解释执行,不执行的地方,有些错误也不影响其他代码的执行
// 作为类库,使用严格模式是很有必要的.严格模式声明必须放到一个namespace空间的最起始处.
var old_public_api = (context || {})[name];
// 最后要返回的对象/函数.
function md5_func(text) {
return hex_md5(text);
// 下面一堆是具体的算法... 可以先不用管
/////////////////////////////////////////////////////
var hexcase = 0;
function hex_md5(a) {
if (a == "")
return rstr2hex(rstr_md5(str2rstr_utf8(a)))
function hex_hmac_md5(a, b) {
return rstr2hex(rstr_hmac_md5(str2rstr_utf8(a), str2rstr_utf8(b)))
function md5_vm_test() {
return hex_md5("abc").toLowerCase() == "cd24fb0de17f72"
function rstr_md5(a) {
return binl2rstr(binl_md5(rstr2binl(a), a.length * 8))
function rstr_hmac_md5(c, f) {
var e = rstr2binl(c);
if (e.length & 16) {
e = binl_md5(e, c.length * 8)
var a = Array(16), d = Array(16);
for (var b = 0; b & 16; b++) {
a[b] = e[b] ^ ;
d[b] = e[b] ^
var g = binl_md5(a.concat(rstr2binl(f)), 512 + f.length * 8);
return binl2rstr(binl_md5(d.concat(g), 512 + 128))
function rstr2hex(c) {
try { hexcase
} catch(g) {
hexcase = 0
var f = hexcase ? "ABCDEF" : "abcdef";
var b = "";
for (var d = 0; d & c. d++) {
a = c.charCodeAt(d);
b += f.charAt((a &&& 4) & 15) + f.charAt(a & 15)
function str2rstr_utf8(c) {
var b = "";
var d = -1;
while (++d & c.length) {
a = c.charCodeAt(d);
e = d + 1 & c.length ? c.charCodeAt(d + 1) : 0;
if (55296 &= a && a &= 56319 && 56320 &= e && e &= 57343) {
a = 65536 + ((a & 1023) && 10) + (e & 1023);
if (a &= 127) {
b += String.fromCharCode(a)
if (a &= 2047) {
b += String.fromCharCode(192 | ((a &&& 6) & 31), 128 | (a & 63))
if (a &= 65535) {
b += String.fromCharCode(224 | ((a &&& 12) & 15), 128 | ((a &&& 6) & 63), 128 | (a & 63))
if (a &= 2097151) {
b += String.fromCharCode(240 | ((a &&& 18) & 7), 128 | ((a &&& 12) & 63), 128 | ((a &&& 6) & 63), 128 | (a & 63))
function rstr2binl(b) {
var a = Array(b.length && 2);
for (var c = 0; c & a. c++) {
for (var c = 0; c & b.length * 8; c += 8) {
a[c && 5] |= (b.charCodeAt(c / 8) & 255) && (c % 32)
function binl2rstr(b) {
var a = "";
for (var c = 0; c & b.length * 32; c += 8) {
a += String.fromCharCode((b[c && 5] &&& (c % 32)) & 255)
function binl_md5(p, k) {
p[k && 5] |= 128 && ((k) % 32);
p[(((k + 64) &&& 9) && 4) + 14] =
var n = -;
var m = -;
for (var g = 0; g & p. g += 16) {
o = md5_ff(o, n, m, l, p[g + 0], 7, -);
l = md5_ff(l, o, n, m, p[g + 1], 12, -);
m = md5_ff(m, l, o, n, p[g + 2], 17, );
n = md5_ff(n, m, l, o, p[g + 3], 22, -);
o = md5_ff(o, n, m, l, p[g + 4], 7, -);
l = md5_ff(l, o, n, m, p[g + 5], 12, );
m = md5_ff(m, l, o, n, p[g + 6], 17, -);
n = md5_ff(n, m, l, o, p[g + 7], 22, -);
o = md5_ff(o, n, m, l, p[g + 8], 7, );
l = md5_ff(l, o, n, m, p[g + 9], 12, -);
m = md5_ff(m, l, o, n, p[g + 10], 17, -42063);
n = md5_ff(n, m, l, o, p[g + 11], 22, -);
o = md5_ff(o, n, m, l, p[g + 12], 7, );
l = md5_ff(l, o, n, m, p[g + 13], 12, -);
m = md5_ff(m, l, o, n, p[g + 14], 17, -);
n = md5_ff(n, m, l, o, p[g + 15], 22, );
o = md5_gg(o, n, m, l, p[g + 1], 5, -);
l = md5_gg(l, o, n, m, p[g + 6], 9, -);
m = md5_gg(m, l, o, n, p[g + 11], 14, );
n = md5_gg(n, m, l, o, p[g + 0], 20, -);
o = md5_gg(o, n, m, l, p[g + 5], 5, -);
l = md5_gg(l, o, n, m, p[g + 10], 9, );
m = md5_gg(m, l, o, n, p[g + 15], 14, -);
n = md5_gg(n, m, l, o, p[g + 4], 20, -);
o = md5_gg(o, n, m, l, p[g + 9], 5, );
l = md5_gg(l, o, n, m, p[g + 14], 9, -);
m = md5_gg(m, l, o, n, p[g + 3], 14, -);
n = md5_gg(n, m, l, o, p[g + 8], 20, );
o = md5_gg(o, n, m, l, p[g + 13], 5, -);
l = md5_gg(l, o, n, m, p[g + 2], 9, -);
m = md5_gg(m, l, o, n, p[g + 7], 14, );
n = md5_gg(n, m, l, o, p[g + 12], 20, -);
o = md5_hh(o, n, m, l, p[g + 5], 4, -378558);
l = md5_hh(l, o, n, m, p[g + 8], 11, -);
m = md5_hh(m, l, o, n, p[g + 11], 16, );
n = md5_hh(n, m, l, o, p[g + 14], 23, -);
o = md5_hh(o, n, m, l, p[g + 1], 4, -);
l = md5_hh(l, o, n, m, p[g + 4], 11, );
m = md5_hh(m, l, o, n, p[g + 7], 16, -);
n = md5_hh(n, m, l, o, p[g + 10], 23, -);
o = md5_hh(o, n, m, l, p[g + 13], 4, );
l = md5_hh(l, o, n, m, p[g + 0], 11, -);
m = md5_hh(m, l, o, n, p[g + 3], 16, -);
n = md5_hh(n, m, l, o, p[g + 6], 23, );
o = md5_hh(o, n, m, l, p[g + 9], 4, -);
l = md5_hh(l, o, n, m, p[g + 12], 11, -);
m = md5_hh(m, l, o, n, p[g + 15], 16, );
n = md5_hh(n, m, l, o, p[g + 2], 23, -);
o = md5_ii(o, n, m, l, p[g + 0], 6, -);
l = md5_ii(l, o, n, m, p[g + 7], 10, );
m = md5_ii(m, l, o, n, p[g + 14], 15, -);
n = md5_ii(n, m, l, o, p[g + 5], 21, -);
o = md5_ii(o, n, m, l, p[g + 12], 6, );
l = md5_ii(l, o, n, m, p[g + 3], 10, -);
m = md5_ii(m, l, o, n, p[g + 10], 15, -1051523);
n = md5_ii(n, m, l, o, p[g + 1], 21, -);
o = md5_ii(o, n, m, l, p[g + 8], 6, );
l = md5_ii(l, o, n, m, p[g + 15], 10, -);
m = md5_ii(m, l, o, n, p[g + 6], 15, -);
n = md5_ii(n, m, l, o, p[g + 13], 21, );
o = md5_ii(o, n, m, l, p[g + 4], 6, -);
l = md5_ii(l, o, n, m, p[g + 11], 10, -);
m = md5_ii(m, l, o, n, p[g + 2], 15, );
n = md5_ii(n, m, l, o, p[g + 9], 21, -);
o = safe_add(o, j);
n = safe_add(n, h);
m = safe_add(m, f);
l = safe_add(l, e)
return Array(o, n, m, l)
function md5_cmn(h, e, d, c, g, f) {
return safe_add(bit_rol(safe_add(safe_add(e, h), safe_add(c, f)), g), d)
function md5_ff(g, f, k, j, e, i, h) {
return md5_cmn((f & k) | ((~f) & j), g, f, e, i, h)
function md5_gg(g, f, k, j, e, i, h) {
return md5_cmn((f & j) | (k & (~j)), g, f, e, i, h)
function md5_hh(g, f, k, j, e, i, h) {
return md5_cmn(f ^ k ^ j, g, f, e, i, h)
function md5_ii(g, f, k, j, e, i, h) {
return md5_cmn(k ^ (f | (~j)), g, f, e, i, h)
function safe_add(a, d) {
var c = (a & 65535) + (d & 65535);
var b = (a && 16) + (d && 16) + (c && 16);
return (b && 16) | (c & 65535)
function bit_rol(a, b) {
return (a && b) | (a &&& (32 - b))
/////////////////////////////////////////////////////
// 避免全局命名空间冲突
md5_func.noConflict = function publicAPI$noConflict() {
if (context) {
// 将那个 name还原回原来的对象
context[name] = old_public_
// 返回自身,由调用的代码自己持有,保存,或赋值给某个变量
return md5_
// 返回的对象,会被绑定到 MD5 之类的名字上,在外部就引用了此对象,
// 因为闭包特性,可以利用到闭包内部方法和内部对象。 lib一般都是利用这种闭包特性,维护私有的属性、对象,
// 对外只暴露一些方法(API),也就是 function, 外面只能调用这些API,方便内部进行逻辑控制,降低依赖.
return md5_
"c4ca820dcc509a6f75849b"
md5(md5("1"))
"28c8edde3d61ab"
4. Oracle 数据库版MD5
注意: 为了与在其他环境下的MD5方法一致,需要转换为小写
需要创建一个存储函数:
CREATE OR REPLACE FUNCTION MD5(passwd IN VARCHAR2) RETURN VARCHAR2 IS
retval varchar2(32);
retval := Lower(utl_raw.cast_to_raw(
DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING =& passwd))
SQL& select MD5('1') as m1, MD5(md5('1')) as m2 from dual
---------------------------------------
---------------------------------------
c4ca820dcc509a6f75849b
28c8edde3d61ab
PS:这里再为大家提供2款MD5加密工具,感兴趣的朋友可以参考一下:
MD5在线加密工具:
在线MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160加密工具:
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 des在线加密解密 的文章

 

随机推荐