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~~

				
时间: 2024-11-11 17:08:27

JAVA 加密算法初探DES&AES的相关文章

Java加密技术(二)对称加密算法DES&amp;AES

接下来我们介绍对称加密算法,最常用的莫过于DES数据加密算法. DES  DES-Data Encryption Standard,即数据加密算法.是IBM公司于1975年研究成功并公开发表的.DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密. DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位. 通过jav

Java加密技术(二)——对称加密算法DES&AES

接下来我们介绍对称加密算法,最常用的莫过于DES数据加密算法. DES DES-Data Encryption Standard,即数据加密算法.是IBM公司于1975年研究成功并公开发表的.DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密. DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位. 通过java

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

[前言] 本文简单的介绍了加密技术相关概念,最后总结了java中现有的加密技术以及用法和样例 [最简单的加密] 1.简单的概念 明文:加密前的信息 密文:机密后的信息 算法:加密或解密的算法 密钥:算法使用的钥匙(读作miyao.正确应该是miyue,可是大家都读miyao) 2.简单的样例 将123456每位数字都加1后得到234567, 当中123456就是明文.234567就是密文.加密密钥就是1,加密算法是每位加 3.对称加密和非对称加密 以上为例. 123456-->234567的加密

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

Java和C/C++进行DES/AES密文传输 声明:对于新手来说很难解决的一个问题,终于在非常煎熬之后找到这篇文章,所以借鉴过来.原文地址http://blog.sina.com.cn/s/blog_48d4cf2d0101eqdf.html. 本来觉得DES.AES这种流行加密算法,使用起来应该很简单.但研究后发现有两个变数:1)分块的方式.加密是逐块进行的.分块方法有:CBC.ECB.CFB……2)padding的方式.当数据的位数不及块的大小时,需要填充.填充方式有:NoPadding.

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

原文链接:http://www.cnblogs.com/sochishun/p/7028056.html 加密技术通常分为两大类:"对称式"和"非对称式". 对称性加密算法:对称式加密就是加密和解密使用同一个密钥.信息接收双方都需事先知道密匙和加解密算法且其密匙是相同的,之后便是对数据进行加解密了.对称加密算法用来对敏感数据等信息进行加密. 非对称算法:非对称式加密就是加密和解密所使用的不是同一个密钥,通常有两个密钥,称为"公钥"和"私

[转]Java加密算法

如基本的单向加密算法: BASE64 严格地说,属于编码格式,而非加密算法 MD5(Message Digest algorithm 5,信息摘要算法) SHA(Secure Hash Algorithm,安全散列算法) HMAC(Hash Message Authentication Code,散列消息鉴别码) 复杂的对称加密(DES.PBE).非对称加密算法: DES(Data Encryption Standard,数据加密算法) PBE(Password-based encryption

C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)

一:异或^简单加解密(数字类型) 1:原理: 异或用于比较两个二进制数的相应位,在执行按位"异或"运算时,如果两个二进制数的相应位都为1或者都为0,则返回0;如果两个二进制数的相应位其中一个为1另一个为0,则返回1. //对数字加密 int P_int_Num, P_int_Key;//定义两个值类型变量 string Encryptstr = (P_int_Num ^ P_int_Key).ToString();//加密数值 //对数字解密 int P_int_Key, P_int_

Java 环境下使用 AES 加密的特殊问题处理

在 Java 环境下使用 AES 加密,在密钥长度和字节填充方面有一些比较特殊的处理. 1. 密钥长度问题 默认 Java 中仅支持 128 位密钥,当使用 256 位密钥的时候,会报告密钥长度错误 Invalid AES key length 你需要下载一个支持更长密钥的包.这个包叫做 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6,可以从这里下载,下载地址:http://www.

java加密算法入门(三)-非对称加密详解

1.简单介绍 这几天一直在看非对称的加密,相比之前的两篇内容,这次看了两倍多的时间还云里雾里的,所以这篇文章相对之前的两篇,概念性的东西多了些,另外是代码的每一步我都做了介绍,方便自己以后翻阅,也方便大家理解.最后就是关于代码的demo,DH算法.RSA算法本文中只有最基础的用法,实际在工作中可能会涉及到密钥的转换X509EncodedKeySpec和PKCS8EncodedKeySpec,相关的demo名分别叫DH2Test,RSA2Test,已经上传GIT.如果对您有帮助,请给我个star.