开发项目中需要将重要数据缓存在本地以便在离线是读取,如果不对数据进行处理,很容易造成损失。所以,我们一般对此类数据进行加密处理。这里,主要介绍两种简单的加密算法: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的更多相关文章

  1. 常用对称加密算法(DES/AES)类(PHP)

    看注释,啥也不说了,欢迎各种跨平台测试! /** * 常用对称加密算法类 * 支持密钥:64/128/256 bit(字节长度8/16/32) * 支持算法:DES/AES(根据密钥长度自动匹配使用: ...

  2. Atitit.加密算法 des  aes 各个语言不同的原理与解决方案java php c#

    Atitit.加密算法 des  aes 各个语言不同的原理与解决方案java php c# 1. 加密算法的参数::算法/模式/填充 1 2. 标准加密api使用流程1 2.1. Md5——16bi ...

  3. Java和C/C++进行DES/AES密文传输(借鉴)

    Java和C/C++进行DES/AES密文传输 声明:对于新手来说很难解决的一个问题,终于在非常煎熬之后找到这篇文章,所以借鉴过来.原文地址http://blog.sina.com.cn/s/blog ...

  4. Java 加密解密 对称加密算法 非对称加密算法 MD5 BASE64 AES RSA

    版权声明:本文为博主原创文章,未经博主允许不得转载. [前言] 本文简单的介绍了加密技术相关概念,最后总结了java中现有的加密技术以及使用方法和例子 [最简单的加密] 1.简单的概念 明文:加密前的 ...

  5. 加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用(转载)

    加密技术通常分为两大类:"对称式"和"非对称式". 对称性加密算法:对称式加密就是加密和解密使用同一个密钥.信息接收双方都需事先知道密匙和加解密算法且其密匙是相 ...

  6. 加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用

    加密技术通常分为两大类:"对称式"和"非对称式". 对称性加密算法:对称式加密就是加密和解密使用同一个密钥.信息接收双方都需事先知道密匙和加解密算法且其密匙是相 ...

  7. [转]加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用

    原文链接:http://www.cnblogs.com/sochishun/p/7028056.html 加密技术通常分为两大类:"对称式"和"非对称式". 对 ...

  8. 密码学之DES/AES算法

    本文示例代码详见:https://github.com/52fhy/crypt-demo DES DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算 ...

  9. java加密算法入门(二)-对称加密详解

    1.简单介绍 什么是对称加密算法? 对称加密算法即,加密和解密使用相同密钥的算法. 优缺点: 优点:算法公开.计算量小.加密速度快.加密效率高. 缺点: (1)交易双方都使用同样钥匙,安全性得不到保证 ...

随机推荐

  1. logout命令详解

    基础命令学习目录首页 logout指令让用户退出系统,其功能和login指令相互对应.语法 logout

  2. JS进阶系列之闭包

    刚刚总结完作用域链,我觉得很有必要马上对闭包总结一下,因为,之前也写过自己对闭包的理解,那时候只知道,闭包就是可以访问别的函数变量的函数,就是在函数里面的函数就叫做闭包,可是并没有深入探究,为什么,可 ...

  3. (第十一周)Beta—review阶段成员贡献分

    项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 个人贡献分=基础分+表现分 基础分=5*5*0.5/5=2.5 成员得分如下: 成员 基础分 表现分 个人贡献 ...

  4. spring boot的maven项目报404错误

    $.ajax({ async: false, type: "POST", url:'searchFileSource', contentType : "applicati ...

  5. OO学习体会与阶段总结(设计与实现)

    前言   在最近的一个月的课程中,笔者对于规格化编程进行了深入的学习.运用面向对象抽象思想对编写的程序进行过程抽象.异常处理.数据抽象.类的层次规格与迭代等等规格设计,使得程序结构化程度提高,具有更好 ...

  6. 计算器简单封装和ASP.net

    封装: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...

  7. Leetcode题库——13.罗马数字转整数

    @author: ZZQ @software: PyCharm @file: Luoma2Int.py @time: 2018/9/16 17:06 要求: 罗马数字转数字 字符 数值 I 1 V 5 ...

  8. 【Coursera】主成分分析

    一.问题 主方向的概念是什么?为什么降低维度的方法是使方差最大化? 假设某两个特征之间成线性关系,在二维平面上的表示就是数据点呈线性分布,那么可以通过将数据在主方向上进行投影,得到一个一维的数据,这个 ...

  9. Anaconda 下libsvm的安装

    方法一. 利用VS生成动态库的安装    详细可参考这篇博文进行操作:https://blog.csdn.net/jeryjeryjery/article/details/72628255 方法二. ...

  10. Internet History, Technology and Security (Week 7)

    Week 7 Technology: Application Protocols Welcome to Week 7 of IHTS. This week has less material than ...