zoukankan      html  css  js  c++  java
  • Java加密解密大全

     
     
     
     
     
    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

  • 相关阅读:
    Coursera机器学习week11 单元测试
    关于 TypeReference 的解释
    getModifiers 方法解释。
    instanceof isInstance isAssignableFrom 比较
    elasticsearch 基础 语法总结
    kibana 启动 关闭 和进程查找
    MD5 SHA1 SHA256 SHA512 SHA1WithRSA 的区别
    spring boot 项目 热启动
    java zip 压缩文件
    Packet for query is too large (1660 > 1024). You can change this value on the server by setting the max_allowed_packet' variable.
  • 原文地址:https://www.cnblogs.com/heartstage/p/3365479.html
Copyright © 2011-2022 走看看