详解DES加密算法及在Java程序中的使用示例_java

DES加密算法
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1976年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),随后在国际上广泛流传开来。
DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是56位,其算法主要分为两步:
1)初始置换
其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则为将输入的第58位换到第一位,第50位换到第2位……依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0是右32位,例:设置换前的输入值为D1D2D3……D64,则经过初始置换后的结果为:L0=D58D50……D8;R0=D57D49……D7。
其置换规则见下表:

58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,

2)逆置换
经过16次迭代运算后,得到L16、R16,将此作为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即得到密文输出。
此算法是对称加密算法体系中的代表,在计算机网络系统中广泛使用.

Java基本实现

package com.stone.security; 

import java.security.Key;
import java.security.SecureRandom; 

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec; 

/**
 * DES 算法    1972美国IBM研制,对称加密算法
 */
public class DES {
  // 算法名称
  public static final String KEY_ALGORITHM = "DES";
  // 算法名称/加密模式/填充方式
  public static final String CIPHER_ALGORITHM_ECB = "DES/ECB/PKCS5Padding";
  public static final String CIPHER_ALGORITHM_CBC = "DES/CBC/PKCS5Padding"; 

  public static void main(String[] args) throws Exception {
    /*
     * 使用 ECB mode
     * 密钥生成器 生成密钥
     * ECB mode cannot use IV
     */
    byte[] key = generateKey();
    byte[] encrypt = encrypt("胃炎F#*(x)".getBytes(), key);
    System.out.println(new String(decrypt(encrypt, key))); 

    /*
     * 使用CBC mode
     * 使用密钥工厂生成密钥,加密 解密
     * iv: DES in CBC mode and RSA ciphers with OAEP encoding operation.
     */
    DESKeySpec dks = new DESKeySpec(generateKey());
    SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
    SecretKey secretKey = factory.generateSecret(dks);
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(getIV()));
    byte[] enc = cipher.doFinal("胃炎A%F#*(x)".getBytes()); //加密 

    cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(getIV()));
    byte[] dec = cipher.doFinal(enc); // 解密
    System.out.println(new String(dec));
  } 

  static byte[] getIV() {
    String iv = "asdfivh7"; //IV length: must be 8 bytes long
    return iv.getBytes();
  } 

  /**
   * 生成密钥
   *
   * @return
   * @throws Exception
   */
  private static byte[] generateKey() throws Exception {
    KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
    keyGenerator.init(56); //des 必须是56, 此初始方法不必须调用
    SecretKey secretKey = keyGenerator.generateKey();
    return secretKey.getEncoded();
  } 

  /**
   * 还原密钥
   *
   * @param key
   * @return
   * @throws Exception
   */
  private static Key toKey(byte[] key) throws Exception {
    DESKeySpec des = new DESKeySpec(key);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
    SecretKey secretKey = keyFactory.generateSecret(des);
    return secretKey;
  } 

  /**
   * 加密
   * @param data 原文
   * @param key
   * @return 密文
   * @throws Exception
   */
  public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
    Key k = toKey(key);
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB);
    cipher.init(Cipher.ENCRYPT_MODE, k, new SecureRandom());
    return cipher.doFinal(data);
  }
  /**
   * 解密
   * @param data 密文
   * @param key
   * @return 明文、原文
   * @throws Exception
   */
  public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
    Key k = toKey(key);
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB);
    cipher.init(Cipher.DECRYPT_MODE, k, new SecureRandom());
    return cipher.doFinal(data);
  }
}

Java三重DES实现:

package com.stone.security; 

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec; 

/**
 * 三重加密 3DES也作 Triple DES,
 */
public class TripleDES {
  // 算法名称
  public static final String KEY_ALGORITHM = "DESede";
  // 算法名称/加密模式/填充方式
  public static final String CIPHER_ALGORITHM_ECB = "DESede/ECB/PKCS5Padding";
  public static final String CIPHER_ALGORITHM_CBC = "DESede/CBC/PKCS5Padding"; 

  private KeyGenerator keyGen;
  private SecretKey secretKey;
  private SecretKey secretKey2;
  private Cipher cipher;
  private static byte[] encryptData; 

  public static void main(String[] args) throws Exception {
    TripleDES tripleDES = new TripleDES("ECB");
    tripleDES.encrypt("sau8jzxlcvm,'123`98(*^&%^^JCB ZX>>A<S<}}{");
    System.out.println("加密后:" + new String(encryptData));
    System.out.println("解密后:"+ new String(tripleDES.decrypt(encryptData))); 

    tripleDES = new TripleDES("CBC");
    tripleDES.encrypt2("sau8jzxlc DQV#><«|vm,'123`98(*^&%^^JCB ZX>>A<S<}}{");
    System.out.println("加密后:" + new String(encryptData));
    System.out.println("解密后:"+ new String(tripleDES.decrypt2(encryptData)));
  } 

  public TripleDES(String mode) throws Exception {
    if ("ECB".equals(mode)) {
//     cipher = Cipher.getInstance(KEY_ALGORITHM);
      cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB);
      keyGen = KeyGenerator.getInstance(KEY_ALGORITHM);
      secretKey = keyGen.generateKey();
    } else if("CBC".equals(mode)) {
      cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
      keyGen = KeyGenerator.getInstance(KEY_ALGORITHM);
      DESedeKeySpec spec = new DESedeKeySpec(keyGen.generateKey().getEncoded());
      secretKey2 = SecretKeyFactory.getInstance(KEY_ALGORITHM).generateSecret(spec);
    }
  }
  /**
   * 加密
   * @param str
   * @return
   * @throws Exception
   */
  public byte[] encrypt(String str) throws Exception {
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    return encryptData = cipher.doFinal(str.getBytes());
  }
  /**
   * 解密
   * @param encrypt
   * @return
   * @throws Exception
   */
  public byte[] decrypt(byte[] encrypt) throws Exception {
    cipher.init(Cipher.DECRYPT_MODE, secretKey);
    return encryptData = cipher.doFinal(encrypt);
  }
  byte[] getIV() {
    return "administ".getBytes();
  }
  /**
   * 加密
   * @param str
   * @return
   * @throws Exception
   */
  public byte[] encrypt2(String str) throws Exception {
    cipher.init(Cipher.ENCRYPT_MODE, secretKey2, new IvParameterSpec(getIV()));
    return encryptData = cipher.doFinal(str.getBytes());
  }
  /**
   * 解密
   * @param encrypt
   * @return
   * @throws Exception
   */
  public byte[] decrypt2(byte[] encrypt) throws Exception {
    cipher.init(Cipher.DECRYPT_MODE, secretKey2, new IvParameterSpec(getIV()));
    return encryptData = cipher.doFinal(encrypt);
  }
} 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 加密
des
des加密解密算法详解、des加密示例c、des加密算法、des加密算法c语言实现、des算法详解,以便于您获取更多的相关知识。

时间: 2024-09-21 03:19:49

详解DES加密算法及在Java程序中的使用示例_java的相关文章

java程序中foreach用法示例_java

语法 复制代码 代码如下: for (Object objectname : preArrayList(一个Object对象的列表)) {} 示例 复制代码 代码如下: package com.kuaff.jdk5;import java.util.*; import java.util.Collection; public class Foreach{private Collection c = null; private String[] belle = new String[4]; pub

java程序中往list中添加对象

问题描述 java程序中往list中添加对象 我有一个类holiday,属性有name和date.先是声明一个list,List list =new ArrayList();然后就holiday hol =new holiday(name,date);最后使用add方法,list.add(hol);这样做是否正确. 可是当我遍历list时,输出的并不是原来定义的name和date,而是,holiday@89ae9e,请问这样对吗?如果我这样在往数据库里存数据是否可以...... 解决方案 楼上正

在Java程序中运行外部类文件

程序 在Java程序中运行外部类文件 一.引言无论是用传统的编程语言(C++.VB等)还是Java语言编程,都经常需要在一个运行的程序中执行另外一个独立的外部程序.例如用Java设计一个IDE程序,那么这个IDE程序就必需能够调式.运行其它独立的外部Java程序.况且直接运行已经存在的外部程序来实现本程序的某些特定的功能,也是提高程序开发效率的一种重要手段.Java2为实现在一个Java程序中运行外部类文件(即Java程序)提供了的两种解决方案,即在同一进程中运行外部类文件和在不同进程中运行外部

Java 程序中的多线程

程序|多线程 在Java程序中使用多线程要比在 C 或 C++ 中容易得多,这是因为 Java 编程语言提供了语言级的支持.本文通过简单的编程示例来说明 Java 程序中的多线程是多么直观.读完本文以后,用户应该能够编写简单的多线程程序. 为什么会排队等待? 下面的这个简单的 Java 程序完成四项不相关的任务.这样的程序有单个控制线程,控制在这四个任务之间线性地移动.此外,因为所需的资源 - 打印机.磁盘.数据库和显示屏 -- 由于硬件和软件的限制都有内在的潜伏时间,所以每项任务都包含

java程序中双重检查锁定与延迟初始化

在java程序中,有时候可能需要推迟一些高开销的对象初始化操作,并且只有在使用这些对象时才进行初始化.此时程序员可能会采用延迟初始化.但要正确实现线程安全的延迟初始化需要一些技巧,否则很容易出现问题.比如,下面是非线程安全的延迟初始化对象的示例代码: public class UnsafeLazyInitialization { private static Instance instance; public static Instance getInstance() { if (instanc

教你怎样在java程序中引入neo4j数据库

随着关系型数据库在某些方面的力不从心,了解当下流行的各种数据库模式的特点和性能,无疑会给我们提供更多的选择和方向. neo4j是一种图形数据库,在遍历和关联查询方面具有突出的优势.废话少说,深入了解neo4j之前,先让我们尝试一下怎样在程序中使用neo4j. neo4j采用java语言开发,如果我们要在java程序中以内嵌方式使用neo4j,只需导入neo4j的对应包即可. 首先,我们来创建一个maven项目并修改pom.xml添加对neo4j的依赖. <?xml version="1.0

Java程序中的配置文件的存放和读取

大家可能经常会遇到在Java程序中存取程序配置文件的需求,比如,为了能够 和不同的数据库连接,我们经常把数据库连接的信息存放到属性文件中,这些信 息一般包括数据库驱动程序类名.数据库连接的URL,数据库的用户名和口令等等 .为了便于程序的安装或部署,我们经常会把这些的配置文件存放到程序安装的 根目录中.由于Java程序用包来分组类,有时候将这些配置文件放入到读取它们 的类所在的包目录中会更好一些.比如,在下面的图示中,将数据库配置文件 database.properties放到数据库读取类所在的

自动检测并行Java程序中的错误

当 CPU 进入多核时代之后,并行编程将更加流行,但是编写并行程序更容易 出错.在开发过程中,工程师能注意到同一个程序在单线程运行时是正确的,但 是在多线程时,它会有可能出错.和并行相关的错误的产生原因通常都非常隐晦 ,而且在一次测试中,它们的出现与否具有很强的随机性.由于程序中多个线程 之间可能以任意的方式交错执行,即使一个并行程序正确的运行了成百上千次, 下一次运行仍然可能出现新的错误. Multi-Thread Run-time Analysis Tool 是由 IBM 为多线程 Java

在Java程序中内嵌Mozilla浏览器

简介 SWT 浏览器部件是 SWT 所提供的众多部件中较为复杂的一个,它提供了在 Java 应用程序中内嵌浏览器应用并通过 Java API 与之进行交互的能力.一个 典型的应用场景是,开发者可以在客户段程序中嵌入一个内置浏览器,访问特定 HTML 应用,从而集 web 技术与客户端技术两者之所长,开发出具有更丰富功能 和界面的软件. 本文主要包含两个方面的内容:1. 如何在 Java 应用程序中内嵌基于 Mozilla 的浏览器部件.2. 使用 JavaXPCOM bridge 定制浏览器功能