IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> java解密加密MD5 -> 正文阅读

[PHP知识库]java解密加密MD5

ava实现加密与解密

  • 密码学的发展历史简介

????纵观密码学的发展史,它共经历了三个阶段,分别是手工加密阶段、机械加密阶段和计算机加密阶段。手工加密阶段最为漫长,期间孕育了古典密码,这为后期密码学的发展奠定了基础。机械工业革命发展的同时促进着各种科学技术的进步,密码学也不例外。加之两次世界大战,更加促进了密码学的飞速发展,密码学由此进入现代密码学阶段。尽管如此,在这一阶段的密码学仍旧未能摆脱古典密码学的影子,加密与解密操作均依赖于语言学的支持,转轮密码机Enigma的发明与破解更是将这一特点发挥到了极致。随着数据理论逐步介入,密码学逐渐成为一门学科,而非一门艺术。进入计算机加密阶段后,密码学应用不再局限于军事、政治和外交领域,逐步扩大到商务、金融和社会的其他领域。密码学的研究和应用已大规模扩展到了民用方面。

??????密码学主要包含两个分支:密码编码学和密码分析学。密码编码学针对于信息如何隐藏;密码分析学针对于信息如何破译。编码学与分析学相互影响,共同促进密码学的发展。

???????古典密码是现代密码的基础,移位和替代是古典密码最常用、最核心的两种加密技巧。由此,古典密码主要分为移位密码和替代密码。例如,凯撒密码就是替代密码的典范。替代密码其分支众多,包含单表替代密码、同音替代密码、多表替代密码和多字母替代密码。移位和替代技巧仍是现代密码学最常用的两种加密手段。

二、现代密码学中的柯克霍夫原则

即使非数学上不可破解,系统也应在实质(应用)程度上无法破解。

系统内不应含任何机密物,即使落入敌人手中也不会造成困扰。

密钥必须易于沟通和记忆,而无需写下,且双方可以很容易地改变密钥。

系统应可以用于电讯。

系统应可以携带,不应需要两个人或两个人以上才能使用(应只要一个人就能使用)。

系统应容易使用,不致让使用者的脑力过分操劳,也无须记得长串的规则。

三、密码体制划分

??????从密码体制上划分,现代密码学工分为两种密码体制:堆成密码体制和非对称密码体制。对称与非对称的差别源于加密密钥和解密密钥是否对称,即加密密钥与解密密钥是否相同(对称)。

??????在对称密码体制中,加密与解密操作使用相同的密钥,我们把这个密钥称为秘密密钥。DES、AES算法都是常用的对称密码算法。流密码实现简单,对环境要求低,适用于手机平台的加密,广泛应用于军事、外交领域。RC4算法就是典型的流密码算法。流密码的理论、算法受限于国家安全因素未能公布。分组密码在这一点上与流密码恰恰相反,其理论,算法公开,分类众多。DES、AES算法主要的对称密码算法均属于分组密码。分组密码共有5中工作模式:电子密码本模式(ECB)、密文链接模式(CBC)、密文反馈模式(CFB)、输出反馈模式(OFB)、计数器模式(CTR)。分组密码会产生短块,关于短块的处理方法有填充法、流密码加密法、密文挪用技术。

????????在非对称密码体制中,加密与解密操作使用不同的密钥。对外公开的密钥,称为公钥;对外保密的密钥,称为私钥。用公钥加密的数据,只能用私钥解密;反之,用私钥加密的数据,只能用公钥解密。RSA算法是常用的非对称密码算法。非对称密码体制同时支持数字签名技术,如RSA、DSA都是常用的数字签名算法。

???????散列函数可以有效地确保数据完整性,其是一项消息认证技术。常用的散列函数算法有MD5、SHA、Mac。散列函数也是数字签名技术中最重要的技术环节。数字签名离不开非对称密码体制,其私钥用于签名,公钥用于验证。基于数字签名的不可伪造性,数字签名技术成为5种安全服务中数据完整性服务、认证性服务和抗否认性服务的核心技术。通信双方只有一方提供数字签名的认证方式称为单向认证,通信双方都提供数字签名的认证方式称为双向认证。一般网银系统多采用单向认证方式,而要求较高的网银交易则都采用双向认证方式。

???????PKI和PGP是现代网络安全技术领域的两把锁。目前电子商务、电子政务使用PKI技术来确保平台安全性。PGP则多用于电子邮件、文件等的数据签名与加密。

???今天给大家介绍一下普遍了解到的加密解密算法MD5

????MD5算法是典型的消息摘要算法,其前身有MD2、MD3和MD4算法,它由MD4、MD3、MD2算法改进而来。不论是哪一种MD算法,它们都需要获得一个随机长度的信息并产生一个128位的信息摘要。如果将这个128位的二进制摘要信息换算成十六进制,可以得到一个32位(每4位二进制数转换为1位十六进制数)的字符串,故我们见到的大部分MD5算法的数字指纹都是32位十六进制的字符串,如本章开篇中,MySQL下载页上的数字指纹(MD5: 5a077abefee447cbb271e2aa7f6d5a47)就是32位的十六进制字符串。现在,各大主流计算机语言均支持MD5算法。

??????虽然,MD5算法漏洞越来越多,已不再安全,但至今我们仍没有看到它的下一版本——MD6算法的出现。或许,同样基于MD4算法改进而来的SHA算法将会是MD系列算法的主要替代者。

让我们一同回顾一下MD算法家族的发展历史。

1. MD2算法

???????1989年,著名的非对称算法RSA发明人之一——麻省理工学院教授罗纳德·李维斯特(Ronald L. Rivest)开发了MD2算法。这个算法首先对信息进行数据补位,使信息的字节长度是16的倍数。再以一个16位的检验和作为补充信息追加到原信息的末尾。最后根据这个新产生的信息计算出一个128位的散列值,MD2算法由此诞生。

???????有关MD2算法详情请参见RFC 1319(http://www.ietf.org/rfc/rfc1319.txt)。

2. MD4算法

????????1990年,罗纳德·李维斯特教授开发出较之MD2算法有着更高安全性的MD4算法。在这个算法中,我们仍需对信息进行数据补位。不同的是,这种补位使其信息的字节长度加上448个字节后能成为512的倍数(信息字节长度mod 512 = 448)。此外,关于MD4算法的处理与MD2又有很大差别。但最终仍旧是会获得一个128位的散列值。MD4算法对后续消息摘要算法起到了推动作用,许多比较有名的消息摘要算法都是在MD4算法的基础上发展而来的,如MD5、SHA-1、RIPE-MD和HAVAL算法等。

???????有关MD4算法的详情请参见RFC 1320(http://www.ietf.org/rfc/rfc1320.txt)。

???????著名开源P2P(Peer-To-Peer,点对点)下载软件EMule(http://www.emule.com)所使用的消息摘要算法正是经过改良后的MD4算法。该算法用于对文件分块后做消息摘要,以验证其文件的完整性。

3. MD5算法

????????1991年,继MD4算法后,罗纳德·李维斯特教授开发了MD5算法,将MD算法推向成熟。MD5算法经MD2、MD3和MD4算法发展而来,算法复杂程度和安全强度大大提高。但不管是MD2、MD4还是MD5算法,其算法的最终结果均是产生一个128位的消息摘要,这也是MD系列算法的特点。MD5算法执行效率略次于MD4算法,但在安全性方面,MD5算法更胜一筹。随着计算机技术的发展和计算水平的不断提高,MD5算法暴露出来的漏洞也越来越多。MD5算法已不再适合安全要求较高的场合使用。

有关MD5算法的详情请参见RFC 1321(http://www.ietf.org/rfc/rfc1321.txt),其中包含了MD2、MD4和MD5三种算法的C语言版实现。

Java代码实现如下

/**

?* 对字符串md5加密

?*

?* @param str

?* @return

?*/

import java.security.MessageDigest;

public static String getMD5(String str) {

?try {

?// 生成一个MD5加密计算摘要

?MessageDigest md = MessageDigest.getInstance("MD5");

?// 计算md5函数

?md.update(str.getBytes());

?// digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符

?// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值

?return new BigInteger(1, md.digest()).toString(16);

?} catch (Exception e) {

?throw new SpeedException("MD5加密出现错误");

?}

}

MD5加密解密类——MyMD5Util,代码如下

package com.zyg.security.md5;

import java.io.UnsupportedEncodingException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.security.SecureRandom;

import java.util.Arrays;

public class MyMD5Util {

?

?private static final String HEX_NUMS_STR="0123456789ABCDEF";

?private static final Integer SALT_LENGTH = 12;

?

?/**

?* 将16进制字符串转换成字节数组

?* @param hex

?* @return

?*/

?public static byte[] hexStringToByte(String hex) {

?int len = (hex.length() / 2);

?byte[] result = new byte[len];

?char[] hexChars = hex.toCharArray();

?for (int i = 0; i < len; i++) {

?int pos = i * 2;

?result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4

?| HEX_NUMS_STR.indexOf(hexChars[pos + 1]));

?}

?return result;

?}

?

?/**

?* 将指定byte数组转换成16进制字符串

?* @param b

?* @return

?*/

?public static String byteToHexString(byte[] b) {

?StringBuffer hexString = new StringBuffer();

?for (int i = 0; i < b.length; i++) {

?String hex = Integer.toHexString(b[i] & 0xFF);

?if (hex.length() == 1) {

?hex = '0' + hex;

?}

?hexString.append(hex.toUpperCase());

?}

?return hexString.toString();

?}

?

?/**

?* 验证口令是否合法

?* @param password

?* @param passwordInDb

?* @return

?* @throws NoSuchAlgorithmException

?* @throws UnsupportedEncodingException

?*/

?public static boolean validPassword(String password, String passwordInDb)

?throws NoSuchAlgorithmException, UnsupportedEncodingException {

?//将16进制字符串格式口令转换成字节数组

?byte[] pwdInDb = hexStringToByte(passwordInDb);

?//声明盐变量

?byte[] salt = new byte[SALT_LENGTH];

?//将盐从数据库中保存的口令字节数组中提取出来

?System.arraycopy(pwdInDb, 0, salt, 0, SALT_LENGTH);

?//创建消息摘要对象

?MessageDigest md = MessageDigest.getInstance("MD5");

?//将盐数据传入消息摘要对象

?md.update(salt);

?//将口令的数据传给消息摘要对象

?md.update(password.getBytes("UTF-8"));

?//生成输入口令的消息摘要

?byte[] digest = md.digest();

?//声明一个保存数据库中口令消息摘要的变量

?byte[] digestInDb = new byte[pwdInDb.length - SALT_LENGTH];

?//取得数据库中口令的消息摘要

?System.arraycopy(pwdInDb, SALT_LENGTH, digestInDb, 0, digestInDb.length);

?//比较根据输入口令生成的消息摘要和数据库中消息摘要是否相同

?if (Arrays.equals(digest, digestInDb)) {

?//口令正确返回口令匹配消息

?return true;

?} else {

?//口令不正确返回口令不匹配消息

?return false;

?}

?}

?/**

?* 获得加密后的16进制形式口令

?* @param password

?* @return

?* @throws NoSuchAlgorithmException

?* @throws UnsupportedEncodingException

?*/

?public static String getEncryptedPwd(String password)

?throws NoSuchAlgorithmException, UnsupportedEncodingException {

?//声明加密后的口令数组变量

?byte[] pwd = null;

?//随机数生成器

?SecureRandom random = new SecureRandom();

?//声明盐数组变量

?byte[] salt = new byte[SALT_LENGTH];

?//将随机数放入盐变量中

?random.nextBytes(salt);

?//声明消息摘要对象

?MessageDigest md = null;

?//创建消息摘要

?md = MessageDigest.getInstance("MD5");

?//将盐数据传入消息摘要对象

?md.update(salt);

?//将口令的数据传给消息摘要对象

?md.update(password.getBytes("UTF-8"));

?//获得消息摘要的字节数组

?byte[] digest = md.digest();

?//因为要在口令的字节数组中存放盐,所以加上盐的字节长度

?pwd = new byte[digest.length + SALT_LENGTH];

?//将盐的字节拷贝到生成的加密口令字节数组的前12个字节,以便在验证口令时取出盐

?System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);

?//将消息摘要拷贝到加密口令字节数组从第13个字节开始的字节

?System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);

?//将字节数组格式加密后的口令转化为16进制字符串格式的口令

?return byteToHexString(pwd);

?}

}

测试类——Client,代码如下

package com.zyg.security.md5;

import java.io.UnsupportedEncodingException;

import java.security.NoSuchAlgorithmException;

import java.util.HashMap;

import java.util.Map;

public class Client {

?private static Map users = new HashMap();

?public static void main(String[] args){

?String userName = "zyg";

?String password = "123";

?registerUser(userName,password);

?userName = "changong";

?password = "456";

?registerUser(userName,password);

?String loginUserId = "zyg";

?String pwd = "1232";

?try {

?if(loginValid(loginUserId,pwd)){

?System.out.println("欢迎登陆!!!");

?}else{

?System.out.println("口令错误,请重新输入!!!");

?}

?} catch (NoSuchAlgorithmException e) {

?// TODO Auto-generated catch block

?e.printStackTrace();

?} catch (UnsupportedEncodingException e) {

?// TODO Auto-generated catch block

?e.printStackTrace();

?}

?}

?/**

?* 注册用户

?*

?* @param userName

?* @param password

?*/

?public static void registerUser(String userName,String password){

?String encryptedPwd = null;

?try {

?encryptedPwd = MyMD5Util.getEncryptedPwd(password);

?users.put(userName, encryptedPwd);

?} catch (NoSuchAlgorithmException e) {

?// TODO Auto-generated catch block

?e.printStackTrace();

?} catch (UnsupportedEncodingException e) {

?// TODO Auto-generated catch block

?e.printStackTrace();

?}

?}

?/**

?* 验证登陆

?*

?* @param userName

?* @param password

?* @return

?* @throws UnsupportedEncodingException

?* @throws NoSuchAlgorithmException

?*/

?public static boolean loginValid(String userName,String password)

?throws NoSuchAlgorithmException, UnsupportedEncodingException{

?String pwdInDb = (String)users.get(userName);

?if(null!=pwdInDb){ // 该用户存在

?return MyMD5Util.validPassword(password, pwdInDb);

?}else{

?System.out.println("不存在该用户!!!");

?return false;

?}

?}

}

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 07:45:54  更:2021-09-19 07:48:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 23:38:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码