JAVA 加密算法初探DES&AES
开发项目中需要将重要数据缓存在本地以便在离线是读取,如果不对数据进行处理,很容易造成损失。所以,我们一般对此类数据进行加密处理。这里,主要介绍两种简单的加密算法:DES&AES。
先简单介绍一下一般的加密方案(如下图所示):
1)明文:原始信息。
2)加密算法:以密钥为参数,对明文进行多种置换和转换的规则和步骤,变换结果为密文。
3)密钥:加密与解密算法的参数,直接影响对明文进行变换的结果。
4)密文:对明文进行变换的结果。
5)解密算法:加密算法的逆变换,以密文为输入、密钥为参数,变换结果为明文。
密码学中常用的数学运算有一下几种:
◆移位和循环移位
移位就是将一段数码按照规定的位数整体性地左移或右移。循环右移就是当右移时,把数码的最后的位移到数码的最前头,循环左移正相反。例如,对十进制数码12345678循环右移1位(十进制位)的结果为81234567,而循环左移1位的结果则为23456781。
◆置换
就是将数码中的某一位的值根据置换表的规定,用另一位代替。它不像移位操作那样整齐有序,看上去杂乱无章。这正是加密所需,被经常应用。
◆扩展
就是将一段数码扩展成比原来位数更长的数码。扩展方法有多种,例如,可以用置换的方法,以扩展置换表来规定扩展后的数码每一位的替代值。
◆压缩
就是将一段数码压缩成比原来位数更短的数码。压缩方法有多种,例如,也可以用置换的方法,以表来规定压缩后的数码每一位的替代值。
◆异或
这是一种二进制布尔代数运算。异或的数学符号为⊕ ,它的运算法则如下:
1⊕1 = 0
0⊕0 = 0
1⊕0 = 1
0⊕1 = 1
也可以简单地理解为,参与异或运算的两数位如相等,则结果为0,不等则为1。
◆迭代
迭代就是多次重复相同的运算,这在密码算法中经常使用,以使得形成的密文更加难以破解。
一、下面就介绍下DES算法:
1、先看下代码实验结果(明文不变,密钥前八位不变):
通过对比发现在对同一明文加密时,只要密钥前八位相同,所产生的密文就相同。由此可以看出,DES采用的密钥长度为64位,进一步了解可以发现,这64位的密钥中只有56位可以用到,其余8位作为奇偶校验(这8位分别是每个字符转化成二进制后的最后一位)。所以,这也是DES如今不常用的原因,现在的电脑通过穷举,24小时之内就可以得到正确的密钥。但作为研究的材料还是可以的。
下面,我们再看一下密钥和明文怎么产生密文的。
在得到原始密钥(即我们输入的密钥)之后,还需要进行一系列的变换,才能产生真正和明文作用的密钥。其中的变换算法这里不作深究。简单的讲下用到的数学运算有:位移、16次迭代。最终形成16套加密密钥:key[0],key[1],key[2],…。key[14],key[15]。这16套密钥是真正参与到密文的生产。
当然,在得到明文之后也需要进行操作,然后和密钥一起生成密文。其中,明文也会进行16次迭代,在每次迭代过程中,与16套中的密钥以此进行异或运算。之后再进一步对迭代之后的数据进行处理,最终得到密文。
加密完成了,自然会涉及到解密。我们可能会认为解密是加密的逆运算。其实不全是。DES采用的解密算法,和加密算法是一样的,不同的是密钥的使用顺序。在加密中是按照第i次迭代就采用第i次迭代生成的密钥进行异或,而解密时第i次迭代就采用第17-i次迭代生成的密钥和数据进行异或。
完整代码如下:
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class des { private final static String DES = "DES"; public static void main(String[] args){
String str_pass = "12345678fedcba";
String content = "不剃头的一休哥";
// String encryptString = encrypt("不剃头的一休哥",str_pass);
byte[] key = str_pass.getBytes();
byte[] src = content.getBytes();
SecureRandom sr = new SecureRandom();
byte[] result = null;
// 从原始密匙数据创建DESKeySpec对象
DESKeySpec dks;
try {
dks = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance(DES);
// 用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
// 正式执行加密操作
result = cipher.doFinal(src);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} String hs = "";
String stmp = "";
for (int n = 0; n < result.length; n++) {
stmp = (java.lang.Integer.toHexString(result[n] & 0XFF));
if (stmp.length() == 1)
hs = hs + "0" + stmp;
else
hs = hs + stmp;
}
String encryptString = hs.toUpperCase();
System.out.println("密钥:"+str_pass);
System.out.println("密文:"+encryptString);
} }
二、AES算法
AES 算法是基于置换和代替的。置换是数据的重新排列,而代替是用一个单元数据替换另一个。具体实现这里不介绍了,感兴趣的朋友可以自行查找。明确地说,AES 是一个迭代的、对称密钥分组的密码,它可以使用128、192 和 256 位密钥,并且用 128 位(16字节)分组加密和解密数据。
先上代码吧
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec; public class Aes { public static void main(String[] args)
{
String content = "不剃头的一休哥";
String password = "12345678fedcba";
try {
KeyGenerator kg = KeyGenerator.getInstance("AES");
SecureRandom sr = new SecureRandom(password.getBytes());
kg.init(128,sr); SecretKey secretKey = kg.generateKey();
System.out.println("SecureRandom:"+sr.toString());
System.out.println("SecretKey:"+secretKey);
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
String str_res = byte2String(result); //
System.out.println("密文:"+str_res);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String byte2String(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1)
hs = hs + "0" + stmp;
else
hs = hs + stmp;
}
return hs.toUpperCase();
}
}
代码中我有些一点解释:
kg.init(128,new SecureRandom(password.getBytes()));
SecretKey secretKey = kg.generateKey();
第一行代码中的随机数可能不同,也就是说kg.init产生的影响可能不同。但是,只要保证password相同,所产生的secretKey就相同。如图所示(DES算法中也用到了随机数,所以也存在此类问题)
查看参考手册可以发现,init函数的作用是 使用用户提供的随机源初始化此密钥生成器,使其具有确定的密钥大小。SecureRandom此类提供强加密随机数生成器。所以,虽然值不同,但是他们同属于一类。我们使用的时候就是用到他们的共同特征。(好牵强,我也没搞懂他们的共同特征是什么o(╯□╰)o)
大概就写这么多吧,有时间查下KeyGenerator.generateKey()的源代码,就能知道他们的共同特征了。然后再作补充。
嗯,加油。
PS:
1、部分内容来源于网上。
2、下周就要真正参与到开发了,周末好好熟悉一下业务流程。O(∩_∩)O~~
JAVA 加密算法初探DES&AES的更多相关文章
- 常用对称加密算法(DES/AES)类(PHP)
看注释,啥也不说了,欢迎各种跨平台测试! /** * 常用对称加密算法类 * 支持密钥:64/128/256 bit(字节长度8/16/32) * 支持算法:DES/AES(根据密钥长度自动匹配使用: ...
- Atitit.加密算法 des aes 各个语言不同的原理与解决方案java php c#
Atitit.加密算法 des aes 各个语言不同的原理与解决方案java php c# 1. 加密算法的参数::算法/模式/填充 1 2. 标准加密api使用流程1 2.1. Md5——16bi ...
- Java和C/C++进行DES/AES密文传输(借鉴)
Java和C/C++进行DES/AES密文传输 声明:对于新手来说很难解决的一个问题,终于在非常煎熬之后找到这篇文章,所以借鉴过来.原文地址http://blog.sina.com.cn/s/blog ...
- Java 加密解密 对称加密算法 非对称加密算法 MD5 BASE64 AES RSA
版权声明:本文为博主原创文章,未经博主允许不得转载. [前言] 本文简单的介绍了加密技术相关概念,最后总结了java中现有的加密技术以及使用方法和例子 [最简单的加密] 1.简单的概念 明文:加密前的 ...
- 加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用(转载)
加密技术通常分为两大类:"对称式"和"非对称式". 对称性加密算法:对称式加密就是加密和解密使用同一个密钥.信息接收双方都需事先知道密匙和加解密算法且其密匙是相 ...
- 加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用
加密技术通常分为两大类:"对称式"和"非对称式". 对称性加密算法:对称式加密就是加密和解密使用同一个密钥.信息接收双方都需事先知道密匙和加解密算法且其密匙是相 ...
- [转]加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用
原文链接:http://www.cnblogs.com/sochishun/p/7028056.html 加密技术通常分为两大类:"对称式"和"非对称式". 对 ...
- 密码学之DES/AES算法
本文示例代码详见:https://github.com/52fhy/crypt-demo DES DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算 ...
- java加密算法入门(二)-对称加密详解
1.简单介绍 什么是对称加密算法? 对称加密算法即,加密和解密使用相同密钥的算法. 优缺点: 优点:算法公开.计算量小.加密速度快.加密效率高. 缺点: (1)交易双方都使用同样钥匙,安全性得不到保证 ...
随机推荐
- OSSEC 架构
OSSEC由很多部分组成,它有一个集中的管理端,用于监控.并接收来自代理.syslog.数据库或无代理设备的日志. 管理端(服务器) 管理端属于OSSEC部署中的中心部分.它存储了文件完整性检测数据库 ...
- PHP 伪协议
1.file:// file://用于访问本地文件系统,不受allow_url_fopen影响 <?php include($_GET['file']); ?> 2.http:// GET ...
- 第十一次ScrumMeeting博客
第十一次ScrumMeeting博客 本次会议于11月29日(三)22时整在3公寓725房间召开,持续30分钟. 与会人员:刘畅.辛德泰张安澜.赵奕.方科栋. 1. 每个人的工作(有Issue的内容和 ...
- PLSQL Developer windows 64位连接数据库的问题
使用PLSQL Developer 工具连接到数据库进行开发,目前主流windows 系统都是64位操作系统,而PLSQL Developer 只有32位程序,所以在连接数据库上遇到一些问题. PL ...
- jenkins配置01--用户添加及权限配置
原文出自:https://www.cnblogs.com/kevingrace/p/6019707.html 下面重点记录下jenkins安装后的一些配置: (1)添加用户权限 jenkins初次登陆 ...
- JS进阶系列之原型、原型链
最近在看 JavaScript忍者秘籍 这本书的时候,再加上最近遇到的关于原型.原型链的面试题,所以萌生了要把这些知识梳理一遍的想法,所以以下是我自己对原型.原型链的看法 什么是原型 提到原型,我们可 ...
- 微信小程序——节奏练耳 宣传页
节奏练耳是什么? 节奏练耳小程序是一款听音练习节奏的交互式小程序.节奏练耳第一大节是辨认六种音符的练习,剩余九大节的练习题中播放的音频是将时值长短不一的音符组合在一起,配合相应的节奏图片,以提高辨认节 ...
- mybatis批量插入oracle
<insert id="batchInsert" parameterType="java.util.List"> INSERT INTO TEST( ...
- Microsoft Visual Studio 2013 的安装及单元测试
题目:练习教科书第22~25页单元测试练习,要求自行安装Visual Studio开发平台,版本至少在2010以上,要求把程序安装过程和练习过程写到博客上,越详细越好,要图文并茂. 安装过程: 1.下 ...
- 实验三:敏捷开发与XP实践
Java实验三报告 一. 实验内容 (一)敏捷开发与XP 内容:1.敏捷开发(Agile Development)是一种以人为核心.迭代.循序渐进的开发方法. 2.极限编程(eXtreme Pro ...