java关于加密

在java 项目中,经过对某些字符串进行加密,然后再进行解密比较等。通常用的方法有
1.MD5 加密
2.DES 加密。
3.自定义加解密方法,通常是位运算得到结果的。

其中 MD5 是不可逆的,DES 可以是可逆的,也可以是不可逆的算法。今天主要用这两种方式分别实现不可逆加密,与可逆加解密的方式。


环境的搭建:
1、新建一个Java工程
2、在工程下新建一个包 com.yihaomen
3、将Source下的类拷贝到新建的包com.yihaomen里面    
4、运行工程就可以调用类EncryptUtil.java里的encrypt()方法就可实现对字符串不可逆加密;
     调用类EncryptUtil.java里的decryptFile()方法就可实现对文件的加密解密;
     调用类StringUtils.java里的encrypt(String password)方法就可现对字符串可逆加密;
     调用类StringUtils.java里的decrypt(String data)方法就可现对字符串可逆解密;

package com.yihaomen;

import java.security.MessageDigest;
import java.io.*;
import javax.crypto.*; 
import javax.crypto.spec.*; 

public class EncryptUtil 
{

// 用MD5不可逆的加密算法,仅限于对字符串加密。
public static String encrypt(String inStr) 
{
    MessageDigest md = null;
    String out = null;

    try 
    {
        md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(inStr.getBytes());
        out = byte2hex(digest);
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }
    return out;
}

private static String byte2hex(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();
}

// 测试用例,不需要传递任何参数,直接执行即可。
public static void main(String[] args)
{
    String str1 = "123";
    String str2 = "this is my first encrypt programe";
    String str3 = "欢迎使用 杰软科技 !";
    String str4 = "#%$?  密钥字符串";
    String str=encrypt(str2);
    System.out.println("outStr1 is : " + str);
    System.out.println("outStr3 is : " + encrypt(str3));
    System.out.println("outStr4 is : " + encrypt(str4));
    System.out.println("解密文件  is : " + decryptFile("E://123//123.txt.jsmt",str1));
    System.out.println("加密文件  is : "+encryptFile("E:\\123\\123.txt",str1));
}


/** 
加密方法 
输入:要加密的文件,密钥字符串
输出: 
对输入的文件加密后,保存到同一文件夹下增加了".jsmt"扩展名的文件中。 
*/ 
public static int encryptFile(String FileName,String sKey)
{ 
    int Rtn=0;
    try
    { 
        // 因为密钥须为32位的字符串,故将用户传递的参数用encrypt方法进行处理;
        //(由0-F组成,共32个字符,我们将其拆解为2个16位的密码后进行二次加密运算)如: 
        // AD67EA2F3BE6E5AD D368DFE03120B5DF

        sKey=encrypt(sKey);
        if(sKey.length() != 32)
        { 
            Rtn=-1;    // sKey is Wrong. //密码长度必须等于32!
            return Rtn;
        }
        byte[] bytK1 = getKeyByStr(sKey.substring(0,16)); 
        byte[] bytK2 = getKeyByStr(sKey.substring(16,32)); 

        File fileIn=new File(FileName);
        if (!fileIn.exists())
        {
            Rtn=-2;    // 需要加密的文件没有找到。
            return Rtn;
        }

        FileInputStream fis = new FileInputStream(fileIn); 
        byte[] bytIn = new byte[(int)fileIn.length()]; 
        for(int i = 0;i<fileIn.length();i++)
        { 
            bytIn[i] = (byte)fis.read(); 
        } 

        //加密 
        byte[] bytOut = encryptByDES(encryptByDES(bytIn,bytK1),bytK2); 
        String fileOut = fileIn.getPath() + ".jsmt"; 
        FileOutputStream fos = new FileOutputStream(fileOut); 
        for(int i = 0;i<bytOut.length;i++)
        { 
            fos.write((int)bytOut[i]); 
        } 
        fos.close(); 
        return Rtn;
    }
    catch(Exception e)
    { 
        Rtn=-3;    // 其他原因导致的加密失败!
        return Rtn;
    } 
} 


/** 
解密函数 
输入: 
要解密的文件,密钥字符串 
输出: 
对制定的文件进行解密处理,保存到用户指定的文件中。(注:待解密的文件扩展名必须为:.jsmt) 
*/ 
private static int decryptFile(String CryptFileName,String sKey)
{ 
    int Rtn=0;    // 默认的返回值为0,成功!
    try
    { 
        // 因为密钥须为32位的字符串,故将用户传递的参数用encrypt方法进行处理;
        //(由0-F组成,共32个字符,我们将其拆解为2个16位的密码后进行二次解密运算)如: 
        // AD67EA2F3BE6E5AD D368DFE03120B5DF

        sKey=encrypt(sKey);
        if(sKey.length()!=32)
        {
            Rtn=-1;    // sKey is Wrong. //密码长度必须等于32!
            return Rtn;
        }

        String strPath = CryptFileName; 
        if(!strPath.substring(strPath.length()-5).toLowerCase().equals(".jsmt"))
        {
            Rtn=-2;    // CryptFileName 扩展名必须为:.jsmt
            return Rtn;
        }

        //用户指定要保存的文件 
        strPath = strPath.substring(0,strPath.length()-5); 
        byte[] bytK1 = getKeyByStr(sKey.substring(0,16)); 
        byte[] bytK2 = getKeyByStr(sKey.substring(16,32)); 

        File fileIn=new File(CryptFileName);
        if (!fileIn.exists())
        {
            Rtn=-3;    // 需要解密的文件没有找到。
            return Rtn;
        }

        FileInputStream fis = new FileInputStream(fileIn); 
        byte[] bytIn = new byte[(int)fileIn.length()]; 
        for(int i = 0;i<fileIn.length();i++)
        { 
            bytIn[i] = (byte)fis.read(); 
        } 

        //解密 
        byte[] bytOut = decryptByDES(decryptByDES(bytIn,bytK2),bytK1); 
        File fileOut =new File(strPath); 
        fileOut.createNewFile(); 
        FileOutputStream fos = new FileOutputStream(fileOut); 
        for(int i = 0;i<bytOut.length;i++)
        { 
            fos.write((int)bytOut[i]); 
        } 
        fos.close(); 
        return Rtn;    // 解密成功
    }
    catch(Exception e)
    { 
        Rtn=-4;    // 其他原因导致的解密失败!
        return Rtn;
    } 
} 


/*
用DES方法加密输入的字节 
bytKey需为8字节长,是加密的密码 
*/ 
private static byte[] encryptByDES(byte[] bytP,byte[] bytKey) throws Exception
{ 
    DESKeySpec desKS = new DESKeySpec(bytKey); 
    SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); 
    SecretKey sk = skf.generateSecret(desKS); 
    Cipher cip = Cipher.getInstance("DES"); 
    cip.init(Cipher.ENCRYPT_MODE,sk); 
    return cip.doFinal(bytP); 
} 

/** 
用DES方法解密输入的字节 
bytKey需为8字节长,是解密的密码 
*/ 
private static byte[] decryptByDES(byte[] bytE,byte[] bytKey) throws Exception
{ 
    DESKeySpec desKS = new DESKeySpec(bytKey); 
    SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); 
    SecretKey sk = skf.generateSecret(desKS); 
    Cipher cip = Cipher.getInstance("DES"); 
    cip.init(Cipher.DECRYPT_MODE,sk); 
    return cip.doFinal(bytE); 
} 

/** 
输入密码的字符形式,返回字节数组形式。 
如输入字符串:AD67EA2F3BE6E5AD 
返回字节数组:{173,103,234,47,59,230,229,173} 
*/ 
private static byte[] getKeyByStr(String str)
{ 
    byte[] bRet = new byte[str.length()/2]; 
    for(int i=0;i<str.length()/2;i++)
    { 
        Integer itg =     new Integer(16*getChrInt(str.charAt(2*i)) + getChrInt(str.charAt(2*i+1))); 
        bRet[i] = itg.byteValue(); 
    } 
    return bRet; 
} 

/** 
计算一个16进制字符的10进制值 
输入:0-F 
*/ 
private static int getChrInt(char chr)
{ 
    int iRet=0; 
    if(chr=="0".charAt(0)) iRet = 0; 
    if(chr=="1".charAt(0)) iRet = 1; 
    if(chr=="2".charAt(0)) iRet = 2; 
    if(chr=="3".charAt(0)) iRet = 3; 
    if(chr=="4".charAt(0)) iRet = 4; 
    if(chr=="5".charAt(0)) iRet = 5; 
    if(chr=="6".charAt(0)) iRet = 6; 
    if(chr=="7".charAt(0)) iRet = 7; 
    if(chr=="8".charAt(0)) iRet = 8; 
    if(chr=="9".charAt(0)) iRet = 9; 
    if(chr=="A".charAt(0)) iRet = 10; 
    if(chr=="B".charAt(0)) iRet = 11; 
    if(chr=="C".charAt(0)) iRet = 12; 
    if(chr=="D".charAt(0)) iRet = 13; 
    if(chr=="E".charAt(0)) iRet = 14; 
    if(chr=="F".charAt(0)) iRet = 15; 
    return iRet; 
} 

}


DES 可逆方式的实现

package com.yihaomen;

import java.security.*; 

import javax.crypto.Cipher; 

import javax.crypto.SecretKey; 

import javax.crypto.SecretKeyFactory; 

import javax.crypto.spec.DESKeySpec; 



/** 

* 字符串工具集合 

* @author yihaomen

*/ 

public class StringUtils { 



private static final String PASSWORD_CRYPT_KEY = "88888888"; 

private final static String DES = "DES"; 



/** 

* 加密 

* @param src 数据源 

* @param key 密钥,长度必须是8的倍数 

* @return  返回加密后的数据 

* @throws Exception 

*/ 

public static byte[] encrypt(byte[] src, byte[] key)throws Exception { 

        //DES算法要求有一个可信任的随机数源 

        SecureRandom sr = new SecureRandom(); 

        // 从原始密匙数据创建DESKeySpec对象 

        DESKeySpec dks = new DESKeySpec(key); 

        // 创建一个密匙工厂,然后用它把DESKeySpec转换成 

        // 一个SecretKey对象 

        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES); 

        SecretKey securekey = keyFactory.generateSecret(dks); 

        // Cipher对象实际完成加密操作 

        Cipher cipher = Cipher.getInstance(DES); 

        // 用密匙初始化Cipher对象 

        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr); 

        // 现在,获取数据并加密 

        // 正式执行加密操作 

        return cipher.doFinal(src); 

     } 



     /** 

     * 解密 

     * @param src 数据源 

     * @param key 密钥,长度必须是8的倍数 

     * @return   返回解密后的原始数据 

     * @throws Exception 

     */ 

     public static byte[] decrypt(byte[] src, byte[] key)throws Exception { 

        // DES算法要求有一个可信任的随机数源 

        SecureRandom sr = new SecureRandom(); 

        // 从原始密匙数据创建一个DESKeySpec对象 

        DESKeySpec dks = new DESKeySpec(key); 

        // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成 

        // 一个SecretKey对象 

        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES); 

        SecretKey securekey = keyFactory.generateSecret(dks); 

        // Cipher对象实际完成解密操作 

        Cipher cipher = Cipher.getInstance(DES); 

        // 用密匙初始化Cipher对象 

        cipher.init(Cipher.DECRYPT_MODE, securekey, sr); 

        // 现在,获取数据并解密 

        // 正式执行解密操作 

        return cipher.doFinal(src); 

     } 

  /** 

   * 密码解密 

   * @param data 

   * @return 

   * @throws Exception 

   */ 

  public final static String decrypt(String data){ 

     try { 

      return new String(decrypt(hex2byte(data.getBytes()),

         PASSWORD_CRYPT_KEY.getBytes())); 

    }catch(Exception e) { 

    } 

    return null; 

  } 

  /** 

   * 密码加密 

   * @param password 

   * @return 

   * @throws Exception 

   */ 

  public final static String encrypt(String password){ 

    try { 

      return byte2hex(encrypt(password.getBytes(),PASSWORD_CRYPT_KEY.getBytes()));
    }catch(Exception e) { 

    } 

    return null; 

  } 

/** 

* 二行制转字符串 

* @param b 

* @return 

*/ 

  public static String byte2hex(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(); 

   } 

   

  public static byte[] hex2byte(byte[] b) { 

    if((b.length%2)!=0) 

       throw new IllegalArgumentException("长度不是偶数"); 

        byte[] b2 = new byte[b.length/2]; 

        for (int n = 0; n < b.length; n+=2) { 

          String item = new String(b,n,2); 

          b2[n/2] = (byte)Integer.parseInt(item,16); 

        } 

    return b2;
  }
  
//测试用例,不需要传递任何参数,直接执行即可。
  public static void main(String[] args)
  {
    String str1="";
      String str3 = "this is 我的 #$%^&()first encrypt program 知道吗?DES算法要求有一个可信任的随机数源 --//*。@@@";
      String str=encrypt(str3);
    String strr=encrypt(str1);
      System.out.println("加密Str3 is : " + str);
      System.out.println("outStr4 is : " + decrypt(str));
      System.out.println("为空时 is : " + decrypt(strr));
  }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值