ChinaSEI系列讲义(By 郭克华)
 
 
Java加密解密方法大全
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
如果有文字等小错,请多包涵。在不盈利的情况下,欢迎免费传播。
版权所有.郭克华
本讲义经过修正、扩充,由清华大学出版社出版。
详细可查询  http://www.china-pub.com/51834
http://product.dangdang.com/product.aspx?product_id=20862469  
 
 
【1】加密概述
〖1-1〗加密的应用
加密是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密
的信息,但因不知解密的方法,仍然无法了解信息的内容。数据加密技术已经广泛应用于
因特网电子商务、手机网络和银行自动取款机等领域。加密系统中有如下重要概念:
1 :明文。被隐蔽的消息称作明文(plaintext )。
2 :密文。隐蔽后的消息称作密文(ciphertext )。
3 .加密。将明文变换成密文的过程称作加密(encryption) 。
4 :解密。由密文恢复出原明文的过程称作解密(decryption) 。
5 :敌方。主要指非授权者,通过各种办法,窃取机密信息。 
6 :被动攻击。获密文进行分析,这类攻击称作被动攻击(passive attack)  。
7 :主动攻击。非法入侵者(tamper) 采用篡改、伪造等手段向系统注入假消息,称为主
动攻击(active attack) 。 
8 :加密算法。对明文进行加密时采用的算法。
9 :解密算法。对密文进行解密时采用算法。 
10:加密密钥和解密密钥。加密算法和解密算法的操作通常是在一组密钥( key )的
控制下进行的,分别称为加密密钥(encryption  key) 和解密密钥(decryption  key) 。 
在加密系统中,加密算法和密钥是最重要的两个概念。在这里需要对加密算法和密钥
进行一个解释。以最简单的“恺撒加密法”为例。
《高卢战记》有描述恺撒曾经使用密码来传递信息,即所谓的“ 恺撒密码” 。它是一种
替代密码,通过将字母按顺序推后 3 位起到加密作用,如将字母 A 换作字母D,将字母 B
换作字母E。如“China”可以变为“Fklqd”;解密过程相反。
在这个简单的加密方法中,“向右移位”,可以理解为加密算法;“3 ”可以理解为加密
密钥。对于解密过程,“向左移位”,可以理解为解密算法;“3 ”可以理解为解密密钥。显
然,密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的数据。
恺撒加密法的安全性来源于两个方面:第一,对加密算法的隐藏;第二,对密钥的隐
蔽。单单隐蔽加密算法以保护信息,在学界和业界已有相当讨论,一般认为是不够安全的。
公开的加密算法是给黑客长年累月攻击测试,对比隐蔽的加密算法要安全多。一般说来,
加密之所以安全,是因为其加密的密钥的隐藏,并非加密解密算法的保密。而流行的一些
加密解密算法一般是完全公开的。敌方如果取得已加密的数据,即使得知加密算法,若没
有密钥,也不能进行解密。
〖1-2〗常见的加密算法
加密技术从本质上说是对信息进行编码和解码的技术。加密是将可读信息(明文)变
为代码形式(密文);解密是加密的逆过程,相当于将密文变为明文。加密算法有很多种,
一般可分为对称加密、非对称加密和单向加密三类算法。
对称加密算法应用较早,技术较为成熟。其过程如下:
 
安全编程技术
1 :发送方将明文和加密密钥一起经过加密算法处理,变成密文,发送出去。
2 :接收方收到密文后,使用加密密钥及相同算法的逆算法对密文解密,恢复为明文。
在对称加密算法中,双方使用的密钥相同,要求解密方事先必须知道加密密钥。其特
点是算法公开、计算量小、加密速度快、加密效率高。不足之处是,通信双方都使用同样
的密钥,安全性得不到保证。此外,用户每次使用该算法,需要保证密钥的唯一性,使得
双方所拥有的密钥数量很大,密钥管理较为困难。对称加密算法中,目前流行的算法有:
DES 、3DES 和IDEA 等,美国国家标准局倡导的AES 即将作为新标准取代DES 。
与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey )和私有
密钥(privatekey)。每个人拥有这两个密钥,公开密钥对外公开,私有密钥不公开。如果
用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进
行加密,那么只有用对应的公开密钥才能解密。 
非对称加密算法的基本过程是:
1 :通信前,接收方随机生成的公钥,发送给发送方,自己保留私钥。
2 :发送方利用接收方的公钥加密明文,使其变为密文。
3 :接收方收到密文后,使用自己的私钥解密密文。
广泛应用的非对称加密算法有RSA 算法和美国国家标准局提出的DSA 。非对称加密
算法的保密性比较好,它消除了最终用户交换密钥的需要,但加密和解密花费时间长、速
度慢,它不适合于对文件加密而只适用于对少量数据进行加密。 
另一类是单向加密算法。该算法在加密过程中不需要使用密钥,输入明文后由系统直
接经过加密算法处理成密文,密文无法解密。只有重新输入明文,并经过同样的加密算法
处理,得到相同的密文并被系统重新识别后,才能真正解密。该方法计算复杂,通常只在
数据量有限的情形下使用,如广泛应用在计算机系统中的口令加密。近年来,单向加密的
应用领域正在逐渐增大。应用较多单向加密算法的有 RSA 公司发明的MD5算法和美国国
家安全局(NSA)  设计,美国国家标准与技术研究院(NIST)  发布SHA (Secure Hash
Algorithm,安全散列算法)。
大多数语言体系(如.net 、Java )都具有相关的 API 支持各种加密算法。本章以Java
语言为例来阐述加密解密过程,这些算法在其他语言中的实现,读者可以参考相关资料。
【2】实现对称加密
如前所述,对称加密算法过程中,发送方将明文和加密密钥一起经过加密算法处理,
变成密文,发送出去;接收方收到密文后,使用加密密钥及相同算法的逆算法对密文解密,
恢复为明文。双方使用的密钥相同,要求解密方事先必须知道加密密钥。从这里可以得出
几个结论:
1 :加密时使用什么密钥,解密时必须使用相同密钥,否则无法解密。
2 :对同样的信息,不同的密钥,加密结果和解密结果理论上不相同。
本节介绍三种流行的对称加密算法:DES 、3DES 和AES 。
〖2-1〗用Java 实现DES
DES 是数据加密标准(Data Encryption Standard )的简称,出自 IBM  的研究工作,
  x 2 x
 
并在 1977  年被美国政府正式采纳。它是使用较为广泛的密钥系统,最初开发DES 是嵌
入硬件中,DES 特别是在保护金融数据的安全,如自动取款机中,使用较多。
在DES 中,使用了一个 56  位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的
分组大小。加密过程中,将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,
然后将输出与另一半进行“异或”运算;接着交换这两半。循环往复。DES 使用16个循
环,但最后一个循环不交换。
攻击 DES,一般只能使用穷举的密钥搜索,即重复尝试各种密钥直到有一个符合为
止。如果 DES使用56位的密钥,则可能的密钥数量是 2
56
个,穷举难度较大。IBM 曾对
DES 拥有几年的专利权,但在1983 年到期。
关于DES 的其他信息,可以参考相关资料。
在对称加密中,解密和加密的密钥一定要相同。以下代码是用Java 语言实现将一个字
符串“郭克华_ 安全编程技术”先加密,然后用同样的密钥解密的过程。不过,由于本书
不是讲解某种语言本身,所以在这里略过Java 加密体系的讲解,在代码中如果出现新的
API,读者可以参考Java 文档。
P12_01.java
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
 
public class P12_01  

  //KeyGenerator提供对称密钥生成器的功能,支持各种算法
     private KeyGenerator keygen;
     //SecretKey负责保存对称密钥 
     private SecretKey deskey;  
     //Cipher 负责完成加密或解密工作
     private Cipher c;
     //该字节数组负责保存加密的结果
     private byte[] cipherByte;    
 
     public P12_01() 
{
        Security.addProvider(new  com.sun.crypto.provider.SunJCE());
         try 
{
           // 实例化支持DES 算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
            keygen = KeyGenerator.getInstance("DES");
  x 3 x
安全编程技术
            // 生成密钥
            deskey = keygen.generateKey();
            // 生成Cipher 对象,指定其支持DES 算法
            c = Cipher.getInstance("DES");
          }
          catch(NoSuchAlgorithmException ex)
{
             ex.printStackTrace();
         }
          catch(NoSuchPaddingException ex)
{
             ex.printStackTrace();
         }
     }
  /*对字符串str 加密*/
     public byte[] createEncryptor(String str) 
{
         try 
{
             // 根据密钥,对Cipher 对象进行初始化,ENCRYPT_MODE 表示加密模式
              c.init(Cipher.ENCRYPT_MODE, deskey);
              byte[] src = str.getBytes();
              // 加密,结果保存进cipherByte
              cipherByte = c.doFinal(src);
         }
         catch(java.security.InvalidKeyException ex)
{
             ex.printStackTrace();
         }
         catch(javax.crypto.BadPaddingException ex)
{
             ex.printStackTrace();
         }
         catch(javax.crypto.IllegalBlockSizeException ex)
{
             ex.printStackTrace();
         }
         return cipherByte;
      }
       /*对字节数组buff 解密*/
  x 4 x
 
      public byte[] createDecryptor(byte[] buff)  
{
         try 
{
           // 根据密钥,对Cipher 对象进行初始化,ENCRYPT_MODE 表示解密模式
            c.init(Cipher.DECRYPT_MODE, deskey);
            // 得到明文,存入cipherByte字符数组
            cipherByte = c.doFinal(buff);
         }
         catch(java.security.InvalidKeyException ex)
{
             ex.printStackTrace();
         }
         catch(javax.crypto.BadPaddingException ex)
{
             ex.printStackTrace();
         }
         catch(javax.crypto.IllegalBlockSizeException ex)
{
             ex.printStackTrace();
         }
         return cipherByte;
      }
            public static void main(String[] args) throws Exception
{
          P12_01 p12_01 = new P12_01();
          String msg = " 郭克华_ 安全编程技术";
          System.out.println("明文是:" + msg);
          byte[] enc = p12_01.createEncryptor(msg);          
          System.out.println("密文是:" + new String(enc));
          byte[] dec = p12_01.createDecryptor(enc);
          System.out.println("解密后的结果是:" + new String(dec));          
      }
}
运行,界面如下:
 
在不同的情况下,密文的内容会不一样。因为KeyGenerator 每次生成的密钥是随机的,
  x 5 x
安全编程技术
这很容易理解,否则DES 算法就没有安全性可言了。
〖2-2〗用Java 实现3DES
3DES,即三重DES ,是DES 的加强版,也是DES 的一个更安全的变形。它使用3
条56位(共168 位)的密钥对数据进行三次加密,一般情况下,提供了较为强大的安全
性。实际上,3DES 是DES 向AES 过渡的加密算法。1999年,NIST将3-DES 指定为过渡
的加密标准。
3DES 以DES 为基本模块,通过组合分组方法设计出分组加密算法。令Ek() 和Dk()
表示DES 算法的加密和解密过程,K 表示DES 算法使用的密钥,P 表示明文,C 表示密
文。3DES 的具体实现过程如下:
1 :加密过程:C=Ek3(Dk2(Ek1(P)))
2 :解密过程为:P=Dk1((EK2(Dk3(C)))
从上述过程可以看出, K1 、K2、K3 决定了算法的安全性。若三个密钥互不相同,
本质上就相当于用一个长为168 位的密钥进行加密。若数据对安全性要求不高,K1可等
于K3。在这种情况下,密钥的有效长度为112 位。
在Java 的加密体系中,使用 3DES 非常简单,程序结构和使用DES 时相同,只不过
在初始化时将算法名称由“DES ”改为“DESede”即可。
下列程序基本原理和P12_01相同,只不过将加密和解密过程写在一起。
P12_02.java
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
 
public class P12_02  
{
            public static void main(String[] args) throws Exception
{
  //KeyGenerator提供对称密钥生成器的功能,支持各种算法
       KeyGenerator keygen;
      //SecretKey 负责保存对称密钥 
      SecretKey deskey; 
      //Cipher 负责完成加密或解密工作
      Cipher c;        
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        // 实例化支持3DES算法的密钥生成器,算法名称用DESede
        keygen = KeyGenerator.getInstance("DESede");
        // 生成密钥
        deskey = keygen.generateKey();
  x 6 x
 
        // 生成Cipher 对象,指定其支持3DES算法
        c = Cipher.getInstance("DESede");                 
         
        String msg = " 郭克华_ 安全编程技术";
        System.out.println("明文是:" + msg);
        
        // 根据密钥,对Cipher 对象进行初始化,ENCRYPT_MODE表示加密模式
        c.init(Ciphe r.ENCRYPT_MODE, deskey);
        byte[] src = msg.getBytes();
        // 加密,结果保存进enc
        byte[] enc = c.doFinal(src);
        System.out.println("密文是:" + new String(enc));  
         
        // 根据密钥,对Cipher 对象进行初始化,ENCRYPT_MODE表示加密模式
        c.init(Ciphe r.DECRYPT_MODE, deskey);
        // 解密,结果保存进dec
        byte[] dec = c.doFinal(enc);
        System.out.println("解密后的结果是:" + new String(dec));  
      }
}
运行,效果如下:
 
〖2-3〗用Java 实现AES
AES 在密码学中是高级加密标准(Advanced Encryption Standard )的缩写,该算法是
美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES ,已经被多方分析
且广为全世界所使用。最近,高级加密标准已然成为对称密钥加密中最流行的算法之一。
AES 算法又称Rijndael 加密法,该算法为比利时密码学家Joan Daemen 和Vincent
Rijmen 所设计,结合两位作者的名字,以 Rijndael命名。AES 是美国国家标准技术研究所
NIST旨在取代DES 的21 世纪的加密标准。
AES 算法将成为美国新的数据加密标准而被广泛应用在各个领域中。尽管人们对AES
还有不同的看法,但总体来说,AES 作为新一代的数据加密标准汇聚了强安全性、高性能、
高效率、易用和灵活等优点。AES 设计有三个密钥长度:128 ,192,256 位,相对而言,
AES 的128 密钥比DES 的56 密钥强得多。AES 算法主要包括三个方面:轮变化、圈数和
密钥扩展。关于其具体实现,读者可以参考密码学书籍。
以下代码是用Java 语言实现 AES 算法,将一个字符串“郭克华_ 安全编程技术”先加
密,然后用同样的密钥解密。在代码中如果出现新的API,读者可以参考Java 文档。
  x 7 x
安全编程技术
P12_03.java
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
 
public class P12_03  
{
  public static void main(String[] args) throws Exception
{
  //KeyGenerator提供对称密钥生成器的功能,支持各种算法
       KeyGenerator keygen;
      //SecretKey 负责保存对称密钥 
      SecretKey deskey; 
      //Cipher 负责完成加密或解密工作
      Cipher c;        
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        // 实例化支持AES 算法的密钥生成器,算法名称用AES
        keygen = KeyGenerator.getInstance("AES");
        // 生成密钥
        deskey = keygen.generateKey();
        // 生成Cipher 对象,指定其支持AES 算法
        c = Cipher.getInstance("AES");                 
         
        String msg = " 郭克华_ 安全编程技术";
        System.out.println("明文是:" + msg);
        
        // 根据密钥,对Cipher 对象进行初始化,ENCRYPT_MODE表示加密模式
        c.init(Ciphe r.ENCRYPT_MODE, deskey);
        byte[] src = msg.getBytes();
        // 加密,结果保存进enc
        byte[] enc = c.doFinal(src);
        System.out.println("密文是:" + new String(enc));  
         
        // 根据密钥,对Cipher 对象进行初始化,ENCRYPT_MODE表示加密模式
        c.init(Ciphe r.DECRYPT_MODE, deskey);
        // 解密,结果保存进dec
        byte[] dec = c.doFinal(enc);
        System.out.println("解密后的结果是:" + new String(dec));  
      }
  x 8 x

Java加密解密大全的更多相关文章

  1. java加密解密的学习

    注:此文章只是对如何学习java加密解密技术做一个讲解.并不涉及具体的知识介绍,如果有需要请留言,有时间我补冲长.个人觉着学习一个学习方法比学习一个知识点更有价值的多. 首先,对于加密解密知识体系没有 ...

  2. Java加密解密字符串

    http://www.cnblogs.com/vwpolo/archive/2012/07/18/2597232.html Java加密解密字符串   旧文重发:http://www.blogjava ...

  3. java加密解密

    java加密解密 public class MD5Util { /** * @param args */ public static void main(String[] args) { System ...

  4. password学4——Java 加密解密之消息摘要算法(MD5 SHA MAC)

    Java 加密解密之消息摘要算法(MD5 SHA MAC) 消息摘要 消息摘要(Message Digest)又称为数字摘要(Digital Digest). 它是一个唯一相应一个消息或文本的固定长度 ...

  5. java加密解密算法位运算

    一.实例说明 本实例通过位运算的异或运算符 “ ^ ” 把字符串与一个指定的值进行异或运算,从而改变每个字符串中字符的值,这样就可以得到一个加密后的字符串.当把加密后的字符串作为程序输入内容,异或运算 ...

  6. ◆JAVA加密解密-3DES

    从数据安全谈起       当你使用网银时,是否担心你的银行卡会被盗用?     当你和朋友用QQ进行聊天时,是否担心你的隐私会被泄露?     作为开发者,编写安全的代码比编写优雅的代码更重要,因为 ...

  7. java加密-解密小结

    加密算法可以分为 双向加密(对称加密.不对称加密) 单向加密(不可逆加密)—— MD5.sha.hmac... 在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密 有: ...

  8. cooking java ——加密解密

    java安全与密码概述 主要分为三部分: 密码学基础,包括:相关术语:分类:常用安全体系. java的安全组成:jdk以及第三方扩展. 相关实现代码,包括:base64.MD5········ 密码学 ...

  9. Java加密解密相关

    关于解释加密解密中的填充方案: http://laokaddk.blog.51cto.com/368606/461279/ 关于对称加密中的反馈模式: http://blog.csdn.net/aaa ...

随机推荐

  1. AnnotationConfigApplicationContext.的用法的核心代码

    public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationCont ...

  2. windows远程桌面访问ubuntu12.04

    转载自 : http://blog.csdn.net/shuzui1985/article/details/7592569 1.dashboard----桌面共享 我们共享所使用的协议是rdp,所以我 ...

  3. mysql5.7.11安装遇到的问题

    首次安装mysql5.7.11绿色版,真是破费功夫,现记录安装中遇到的问题,只是解决了问题,而不清楚问题的由来. 问题一: 问题二: 问题三: 问题四: 我的my.ini配置文件: [mysql] # ...

  4. linux下使用wget下载整个网站

    linux下可以用wget下载整个网站,而且网站链接中包含utf-8编码的中文也能正确处理. 简要方法记录如下: wget --restrict-file-name=ascii -m -c -nv - ...

  5. Jasper语音助理

    1. 介绍 Jasper是一款基于树莓派的开源语音控制助理, 使用Python语言开发. Jasper工作原理主要是设备被动监听麦克风, 当收到唤醒关键字时进入主动监听模式, 此时收到语音指令后进行语 ...

  6. JSP(1) - JSP简介、原理、语法 - 小易Java笔记

    1.JSP简介 (1)JSP的全称是Java Server Pages(运行在服务器端的页面),实际就是Servlet(学习JSP的关键就是时刻联想到Servlet) (2)JSP.Servlet各自 ...

  7. 【LVS 】NAT方式实现过程

    LVS-NAT方式实现负载均衡 一.环境介绍

  8. idea打包jar的多种方式,用IDEA自带的打包形式,用IDEA自带的打包形式 用Maven插件maven-shade-plugin打包,用Maven插件maven-assembly-plugin打包

    这里总结出用IDEA打包jar包的多种方式,以后的项目打包Jar包可以参考如下形式: 用IDEA自带的打包形式 用Maven插件maven-shade-plugin打包 用Maven插件maven-a ...

  9. 【C++】this指针

    来自:黄邦勇帅 this 指针是所有成员函数的隐含指针,每次调用成员函数时,this 指针就指向调用此函数的对象.可以在成员函数类 部使用显使用this 指针. 友元函数不是类的成员函数,所以友元函数 ...

  10. eclipse中的project 和classpath文件的具体作用

    项目->右键 Properties-> java Build Path -> source: xxx/data xxx/src 体现在 .classpath文件中: .classpa ...