当前位置: 移动技术网 > IT编程>开发语言>Java > java基于Des对称加密算法实现的加密与解密功能详解

java基于Des对称加密算法实现的加密与解密功能详解

2019年07月22日  | 移动技术网IT编程  | 我要评论

绿茶冲泡视频,轰天神鹰,热血燃烧大时代txt

本文实例讲述了java基于des对称加密算法实现的加密与解密功能。分享给大家供大家参考,具体如下:

des 加密相关类介绍:

securerandom  这个类是继承自java.util.random 这个类

securerandom 这个类的构造器有三种,下面例举两种:

securerandom()构造一个实现默认随机数算法的安全随机数生成器 (rng)。

securerandom(byte[] seed)构造一个实现默认随机数算法的安全随机数生成器 (rng)。

deskeyspec 这个类是用来使用原始秘钥来生成秘钥的秘钥内容

deskeyspec 有两个构造函数:

deskeyspec(byte[] key) 创建一个 deskeyspec 对象,使用 key 中的前 8 个字节作为 des 密钥的密钥内容。

deskeyspec(byte[] key, int offset) 创建一个 deskeyspec 对象,使用 key 中始于且包含 offset 的前 8 个字节作为 des-ede 密钥的密钥内容。

secretkeyfactory , 密钥工厂用来将密钥(类型 key 的不透明加密密钥)转换为密钥规范(底层密钥材料的透明表示形式),反之亦然。秘密密钥工厂只对秘密(对称)密钥进行操作。

secretkey对象,秘钥对象,通过调用秘钥工厂的generatesecret(deskeyspec deskeyspace) 方法来生成秘钥

cipher 类为加密和解密提供密码功能,通过调用cipher的getinstance("des") 来获取实例

cipher 对象调用init() 方法进行对象的初始化,init() 方法的具体参数按照具体情况而定,有加密的也有解密的常量

最后调用cipher的dofinal() 方法进行加密解密。

在这里请教大家一个问题,不管是第一种使用base64encoder编码还是第二种org.apache.commons.codec.binary.base64编码,在将string 转化为byte以及将byte转化为string 时需要 utf-8/gbk 等编码来编码,解码吗?

一、使用了 sun.misc.base64decoder 和base64encoder 进行解码,编码

package com.soufun.com;
import java.io.ioexception;
import java.security.nosuchalgorithmexception;
import java.security.securerandom;
import java.util.date;
import javax.crypto.cipher;
import javax.crypto.secretkey;
import javax.crypto.secretkeyfactory;
import javax.crypto.spec.deskeyspec;
// 导入sun的64位编码
import sun.misc.base64decoder;
import sun.misc.base64encoder;
/**
 *@author whd
 *
 *即使导入sun.misc这个架包也会报错,这时首先把你的jre架包移除再导入一次就可以了
 */
public class desutil {
  // 定义加密方式
   private final static string des = "des";
   private final static string utf8="gbk";
   static secretkeyfactory keyfactory = null;
  static {
    try {
      keyfactory=secretkeyfactory.getinstance("des");
    } catch (nosuchalgorithmexception e) {
      // todo auto-generated catch block
      e.printstacktrace();
    }
  }
    public static void main(string[] args) throws exception {
      long begin=new date().gettime();
      string data = "aaades加密测试";
      // 注意:des加密和解密过程中,密钥长度都必须是8的倍数
      string key = "qazwsxed";
      system.err.println(encrypt(data, key));
      system.err.println(decrypt(encrypt(data, key), key));
      long end =new date().gettime();
      system.out.println(end-begin);
    }
    /**
     * description 根据键值进行加密
     * @param data
     * @param key 加密键byte数组
     * @return
     * @throws exception
     */
    public static string encrypt(string data, string key) throws exception {
      // 使用指定的编码获取要加密的内容,一般秘钥都是字母或数字不用指定编码,但指定也可以
      byte[] bt = encrypt(data.getbytes(utf8), key.getbytes(utf8));
      //注意:在加密和解密的时候使用sun的base64encoder()进行编码和解码不然会有乱码
      //网上查看了很多实例,都没有编码和解码,也说没有乱码问题,而我这里出现了乱码,所以使用base64encoder()进行了编码解码
      string strs = new base64encoder().encode(bt);
      return strs;
    }
    /**
     * description 根据键值进行解密
     * @param data
     * @param key 加密键byte数组
     * @return
     * @throws ioexception
     * @throws exception
     */
    public static string decrypt(string data, string key) throws ioexception,
        exception {
      if (data == null)
        return null;
      //注意:在加密和解密的时候使用sun的base64encoder()进行编码和解码不然会有乱码
      base64decoder decoder = new base64decoder();
      byte[] buf = decoder.decodebuffer(data);
      byte[] bt = decrypt(buf,key.getbytes());
      return new string(bt,utf8);
    }
    /**
     * description 根据键值进行加密
     * @param data
     * @param key 加密键byte数组
     * @return
     * @throws exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws exception {
      // 生成一个可信任的随机数源
      securerandom sr = new securerandom();
      // 从原始密钥数据创建deskeyspec对象,也就是创建秘钥的秘钥内容
      deskeyspec dks = new deskeyspec(key);
      // 密钥工厂用来将密钥(类型 key 的不透明加密密钥)转换为密钥规范(底层密钥材料的透明表示形式),反之亦然。秘密密钥工厂只对秘密(对称)密钥进行操作。
      // 这里改为使用单例模式
      //secretkeyfactory keyfactory = secretkeyfactory.getinstance(des);
      //根据提供的密钥规范(密钥材料)生成 secretkey(秘钥) 对象。
      secretkey securekey = keyfactory.generatesecret(dks);
      // cipher对象实际完成加密操作,此类为加密和解密提供密码功能
      cipher cipher = cipher.getinstance(des);
      // 用密钥和随机源初始化此 cipher。encrypt_mode用于将 cipher 初始化为加密模式的常量。
      cipher.init(cipher.encrypt_mode, securekey, sr);
      //正式执行加密操作
      return cipher.dofinal(data);
    }
    /**
     * description 根据键值进行解密
     * @param data
     * @param key 加密键byte数组
     * @return
     * @throws exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) throws exception {
      // 生成一个可信任的随机数源
      securerandom sr = new securerandom();
      // 从原始密钥数据创建deskeyspec对象,也就是创建秘钥的秘钥内容
      deskeyspec dks = new deskeyspec(key);
      // 密钥工厂用来将密钥(类型 key 的不透明加密密钥)转换为密钥规范(底层密钥材料的透明表示形式),反之亦然。秘密密钥工厂只对秘密(对称)密钥进行操作。
      // 这里改为使用单例模式
      //secretkeyfactory keyfactory = secretkeyfactory.getinstance(des);
      //根据提供的密钥规范(密钥材料)生成 secretkey(秘钥)对象。
      secretkey securekey = keyfactory.generatesecret(dks);
      // cipher类为加密和解密提供密码功能
      cipher cipher = cipher.getinstance(des);
      // decrypt_mode用于将 cipher 初始化为解密模式的常量。
      cipher.init(cipher.decrypt_mode, securekey, sr);
      // 正式进行解密操作
      return cipher.dofinal(data);
    }
}

二、使用org.apache.commons.codec.binary.base64 进行解码,编码

package com.soufun.com;
import java.io.ioexception;
import java.security.nosuchalgorithmexception;
import java.security.securerandom;
import java.util.date;
import javax.crypto.cipher;
import javax.crypto.secretkey;
import javax.crypto.secretkeyfactory;
import javax.crypto.spec.deskeyspec;
import org.apache.commons.codec.binary.base64;
/**
 *@author whd
 *
 */
public class desutil {
  // 定义加密方式
   private final static string des = "des";
   private final static string utf8="gbk";
   static secretkeyfactory keyfactory = null;
  static {
    try {
      keyfactory=secretkeyfactory.getinstance("des");
    } catch (nosuchalgorithmexception e) {
      // todo auto-generated catch block
      e.printstacktrace();
    }
  }
    public static void main(string[] args) throws exception {
      long begin=new date().gettime();
      string data = "aaades加密测试";
      // 注意:des加密和解密过程中,密钥长度都必须是8的倍数
      string key = "qazwsxed";
      system.err.println(encrypt(data, key));
      system.err.println(decrypt(encrypt(data, key), key));
      long end =new date().gettime();
      system.out.println(end-begin);
    }
    /**
     * description 根据键值进行加密
     * @param data
     * @param key 加密键byte数组
     * @return
     * @throws exception
     */
    public static string encrypt(string data, string key) throws exception {
      // 使用指定的编码获取要加密的内容,一般秘钥都是字母或数字不用指定编码,但指定也可以
      byte[] bt = encrypt(data.getbytes(utf8), key.getbytes());
      // 第一个使用了sun.misc.base64encoder;进行了编码,但网上说使用org.apache.commons.codec.binary.base64比较好所以拿来试试
      string strs = base64.encodebase64string(bt);
      return strs;
    }
    /**
     * description 根据键值进行解密
     * @param data
     * @param key 加密键byte数组
     * @return
     * @throws ioexception
     * @throws exception
     */
    public static string decrypt(string data, string key) throws ioexception,
        exception {
      if (data == null)
        return null;
      // 使用org.apache.commons.codec.binary.base64解码
      byte [] buf=base64.decodebase64(data);
      byte[] bt = decrypt(buf,key.getbytes());
      return new string(bt,utf8);
    }
    /**
     * description 根据键值进行加密
     * @param data
     * @param key 加密键byte数组
     * @return
     * @throws exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws exception {
      // 生成一个可信任的随机数源
      securerandom sr = new securerandom();
      // 从原始密钥数据创建deskeyspec对象,也就是创建秘钥的秘钥内容
      deskeyspec dks = new deskeyspec(key);
      // 密钥工厂用来将密钥(类型 key 的不透明加密密钥)转换为密钥规范(底层密钥材料的透明表示形式),反之亦然。秘密密钥工厂只对秘密(对称)密钥进行操作。
      // 这里改为使用单例模式
      //secretkeyfactory keyfactory = secretkeyfactory.getinstance(des);
      //根据提供的密钥规范(密钥材料)生成 secretkey(秘钥) 对象。
      secretkey securekey = keyfactory.generatesecret(dks);
      // cipher对象实际完成加密操作,此类为加密和解密提供密码功能
      cipher cipher = cipher.getinstance(des);
      // 用密钥和随机源初始化此 cipher。encrypt_mode用于将 cipher 初始化为加密模式的常量。
      cipher.init(cipher.encrypt_mode, securekey, sr);
      //正式执行加密操作
      return cipher.dofinal(data);
    }
    /**
     * description 根据键值进行解密
     * @param data
     * @param key 加密键byte数组
     * @return
     * @throws exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) throws exception {
      // 生成一个可信任的随机数源
      securerandom sr = new securerandom();
      // 从原始密钥数据创建deskeyspec对象,也就是创建秘钥的秘钥内容
      deskeyspec dks = new deskeyspec(key);
      // 密钥工厂用来将密钥(类型 key 的不透明加密密钥)转换为密钥规范(底层密钥材料的透明表示形式),反之亦然。秘密密钥工厂只对秘密(对称)密钥进行操作。
      // 这里改为使用单例模式
      //secretkeyfactory keyfactory = secretkeyfactory.getinstance(des);
      //根据提供的密钥规范(密钥材料)生成 secretkey(秘钥)对象。
      secretkey securekey = keyfactory.generatesecret(dks);
      // cipher类为加密和解密提供密码功能
      cipher cipher = cipher.getinstance(des);
      // decrypt_mode用于将 cipher 初始化为解密模式的常量。
      cipher.init(cipher.decrypt_mode, securekey, sr);
      // 正式进行解密操作
      return cipher.dofinal(data);
    }
}

一、二中使用到的架包下载地址:

下载: 。
下载: 。

三、未使用任何编码,解码架包

package com.soufun.com;
import java.io.ioexception;
import java.security.nosuchalgorithmexception;
import java.util.date;
import java.util.hashmap;
import java.util.map;
import javax.crypto.cipher;
import javax.crypto.secretkey;
import javax.crypto.secretkeyfactory;
import javax.crypto.spec.deskeyspec;
import javax.crypto.spec.ivparameterspec;
/**
 *@author whd
 *
 */
public class descrypt {
  static secretkeyfactory secretkeyfactory = null;
  //cipher 的“算法/模式/填充”
  static final string cipher = "des/cbc/pkcs5padding";
  static {
    try {
      // 在静态代码块中获取秘钥工程
      secretkeyfactory = secretkeyfactory.getinstance("des");
    } catch (nosuchalgorithmexception e) {
      e.printstacktrace();
    }
  }
  // 定义常量 ,编码格式
  private static final string utf8 = "gbk";
  /*
   * 对象缓存的容器
   */
  static abstract class cache {
    private final map innercache = new hashmap();
    protected abstract object createvalue(object key) throws exception;
    public object get(object key) throws exception {
      object value;
      synchronized (innercache) {
        value = innercache.get(key);
        if (value == null) {
          value = new creationplaceholder();
          innercache.put(key, value);
        }
      }
      if (value instanceof creationplaceholder) {
        synchronized (value) {
          creationplaceholder progress = (creationplaceholder) value;
          if (progress.value == null) {
            progress.value = createvalue(key);
            synchronized (innercache) {
              innercache.put(key, progress.value);
            }
          }
          return progress.value;
        }
      }
      return value;
    }
    static final class creationplaceholder {
      object value;
    }
  }
  /*
   * hex->str & str->hex
   */
  public static byte[] stringtohex(string ss) {
    // 字符串转化we
    byte digest[] = new byte[ss.length() / 2];
    for (int i = 0; i < digest.length; i++) {
      string bytestring = ss.substring(2 * i, 2 * i + 2);
      int bytevalue = integer.parseint(bytestring, 16);
      digest[i] = (byte) bytevalue;
    }
    return digest;
  }
  public static string hextostring(byte b[]) {
    stringbuffer hexstring = new stringbuffer();
    for (int i = 0; i < b.length; i++) {
      string plaintext = integer.tohexstring(0xff & b[i]);
      if (plaintext.length() < 2) {
        hexstring.append("0");
      }
      hexstring.append(plaintext);
    }
    return hexstring.tostring();
  }
  private static byte[] _convertkeyiv(string text) throws ioexception {
    if (text.length() == 8) {
      return text.getbytes(utf8);
    }
    if (text.startswith("0x") && text.length() == 32) {
      byte[] result = new byte[8];
      for (int i = 0; i < text.length(); i += 2) {
        if (text.charat(i++) == '0' && text.charat(i++) == 'x') {
          try {
            result[i / 4] = (byte) integer.parseint(
                text.substring(i, i + 2), 16);
          } catch (exception e) {
            throw new ioexception("txt '" + text + "' is invalid!");
          }
        }
      }
      return result;
    }
    throw new ioexception("txt '" + text + "' is invalid!");
  }
  /*
   * secretkey & ivparameterspec的缓存
   */
  private static cache secretkeyspecs = new cache() {
    protected object createvalue(object key) throws exception {
      secretkey secretkeyobj = null;
      try {
        secretkeyobj = secretkeyfactory.generatesecret(new deskeyspec(
            _convertkeyiv((string) key)));
      } catch (exception e) {
        e.printstacktrace();
      }
      return secretkeyobj;
    }
  };
  private static cache ivparamspecs = new cache() {
    protected object createvalue(object key) throws exception {
      ivparameterspec ivobj = null;
      ivobj = new ivparameterspec(_convertkeyiv((string) key));
      return ivobj;
    }
  };
  /*
   * 加密&解密
   */
  public static string encrypt(string text, string authkey, string authiv) {
    secretkey secretkeyobj = null;
    ivparameterspec ivobj = null;
    try {
      secretkeyobj = (secretkey) secretkeyspecs.get(authkey);
      ivobj = (ivparameterspec) ivparamspecs.get(authiv);
    } catch (exception e) {
      e.printstacktrace();
    }
    byte[] data = null;
    try {
      data = text.getbytes(utf8);
    } catch (exception e) {
      e.printstacktrace();
    }
    byte[] authtoken = null;
    try {
      authtoken = encrypt(data, secretkeyobj, ivobj);
    } catch (exception e) {
      e.printstacktrace();
    }
    return hextostring(authtoken);
  }
  public static byte[] encrypt(byte[] data, secretkey secretkey,
      ivparameterspec iv) throws exception {
    cipher cipher = cipher.getinstance(cipher);
    cipher.init(cipher.encrypt_mode, secretkey, iv);
    return cipher.dofinal(data);
  }
  public static string decrypt(string hexstring, string authkey, string authiv)
      throws exception {
    secretkey secretkeyobj = null;
    ivparameterspec ivobj = null;
    try {
      secretkeyobj = (secretkey) secretkeyspecs.get(authkey);
      ivobj = (ivparameterspec) ivparamspecs.get(authiv);
    } catch (exception e) {
      e.printstacktrace();
    }
    string text = decrypt(hexstring, secretkeyobj, ivobj);
    return text;
  }
  public static string decrypt(string message, secretkey secretkey,
      ivparameterspec iv) throws exception {
    byte[] data = stringtohex(message);
    return decrypt(data, secretkey, iv);
  }
  public static string decrypt(byte[] data, secretkey secretkey,
      ivparameterspec iv) throws exception {
    cipher cipher = cipher.getinstance(cipher);
    cipher.init(cipher.decrypt_mode, secretkey, iv);
    byte[] retbyte = cipher.dofinal(data);
    return new string(retbyte);
  }
  public static void main(string[] args) throws exception {
    long begin= new date().gettime();
    string authkey = "w8f3k9c2";
    string authiv = "w8f3k9c2";
    string text = "aaades加密测试";
    // 140cb412ba03869f
    // 140cb412ba03869f
    // 对原文进行加密
    string encryptedtext = encrypt(text, authkey, authiv);
    system.out.println("encryptedtext:" + encryptedtext);
    // 对密文进行还原
    string plaintext = decrypt(encryptedtext, authkey, authiv);
    system.out.println("plaintext:" + plaintext);
    //2a329740ce15f549be64190b183a5be2
    long end =new date().gettime();
    system.out.println(end-begin);
  }
}

ps:关于加密解密感兴趣的朋友还可以参考本站在线工具:

密码安全性在线检测:

高强度密码生成器:

迅雷、快车、旋风url加密/解密工具:

在线散列/哈希算法加密工具:

在线md5/hash/sha-1/sha-2/sha-256/sha-512/sha-3/ripemd-160加密工具:

在线sha1/sha224/sha256/sha384/sha512加密工具:

希望本文所述对大家java程序设计有所帮助。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网