java 加密算法-des、md5、aes、base64、rsa

最近在工作設計APP接口校驗時用到java加密算法,從網上找了些資料,在此整理做下記錄方便以後查閱。
AES加密:

package com.jimi.exapp.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 使用MD5算法對字符串進行加密的工具類
 * 
 */
public class MD5Utils {

    public static String encode(String msg) { 
        String encodeStr = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");  
            md.update(msg.getBytes());
            encodeStr = toHex(md.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }  
        return encodeStr;  
    } 

    private static String toHex(byte buffer[]) {  
        StringBuffer sb = new StringBuffer(buffer.length * 2);  
        for (int i = 0; i < buffer.length; i++) {  
            sb.append(Character.forDigit((buffer[i] & 240) >> 4, 16));  
            sb.append(Character.forDigit(buffer[i] & 15, 16));  
        }  

        return sb.toString();  
    }
}

DES+base64
這裏不是採用jdk自帶的base64,因爲jdk自帶base64加密後的字符都會有換行,所以這裏選擇使用commons-codec.jar帶有的加密算法。
commons-codec.jar的pom

      <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.10</version>
      </dependency>
package com.jimi.exapp.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;

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

import org.apache.commons.codec.binary.Base64;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class DesUtil {

    private final static String DES = "DES";

    /**
     * Description 根據鍵值進行加密
     * @param data 
     * @param key  加密鍵byte數組
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String key){
        String strs="";
        try {
            byte[] bt = encrypt(data.getBytes("UTF-8"), key.getBytes());
            //strs = new BASE64Encoder().encode(bt);
            strs = Base64.encodeBase64String(bt);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strs;
    }

    /**
     * Description 根據鍵值進行解密
     * @param data
     * @param key  加密鍵byte數組
     * @return
     * @throws IOException
     * @throws Exception
     */
    public static String decrypt(String data, String key){
        String decryptStr = "";
        if (data != null){
            try {
                /*BASE64Decoder decoder = new BASE64Decoder();
                byte[] buf = decoder.decodeBuffer(data);*/
                byte[] buf = Base64.decodeBase64(data);
                byte[] bt = decrypt(buf,key.getBytes());
                decryptStr = new String(bt, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return decryptStr;
    }

    /**
     * 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);

        // 創建一個密鑰工廠,然後用它把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(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);

        // 創建一個密鑰工廠,然後用它把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(data);
    }
}

base64加密

/*
 *  Copyright (c) 2013 The CCP project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a Beijing Speedtong Information Technology Co.,Ltd license
 *  that can be found in the LICENSE file in the root of the web site.
 *
 *   http://www.cloopen.com
 *
 *  An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
package com.jimi.exapp.util;

import java.io.UnsupportedEncodingException;

import org.apache.commons.codec.binary.Base64;


public class EncryptUtil {

    private static final String UTF8 = "utf-8";

    /**
     * BASE64編碼
     * 
     * @param src
     * @return
     * @throws Exception
     */
    public static String base64Encoder(String src){
        String str = "";
        try {
            str = Base64.encodeBase64String(src.getBytes(UTF8));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * BASE64解碼
     * 
     * @param dest
     * @return
     * @throws Exception
     */
    public static String base64Decoder(String dest) {
        String str = "";
        try {
            str = new String(Base64.decodeBase64(dest), UTF8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return str;
    }
}

MD5

package com.jimi.exapp.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 使用MD5算法對字符串進行加密的工具類
 * 
 */
public class MD5Utils {

    public static String encode(String msg) { 
        String encodeStr = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");  
            md.update(msg.getBytes());
            encodeStr = toHex(md.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }  
        return encodeStr;  
    } 

    private static String toHex(byte buffer[]) {  
        StringBuffer sb = new StringBuffer(buffer.length * 2);  
        for (int i = 0; i < buffer.length; i++) {  
            sb.append(Character.forDigit((buffer[i] & 240) >> 4, 16));  
            sb.append(Character.forDigit(buffer[i] & 15, 16));  
        }  

        return sb.toString();  
    }
}

RSA

package com.jimi.exapp.util;

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.HashMap;

import javax.crypto.Cipher;

public class RSAUtils {  

    /** 
     * 生成公鑰和私鑰 
     * @throws NoSuchAlgorithmException  
     * 
     */  
    public static HashMap<String, Object> getKeys() throws NoSuchAlgorithmException{  
        HashMap<String, Object> map = new HashMap<String, Object>();  
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");  
        keyPairGen.initialize(1024);  
        KeyPair keyPair = keyPairGen.generateKeyPair();  
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
        map.put("public", publicKey);  
        map.put("private", privateKey);  
        return map;  
    }  
    /** 
     * 使用模和指數生成RSA公鑰 
     * 注意:【此代碼用了默認補位方式,爲RSA/None/PKCS1Padding,不同JDK默認的補位方式可能不同,如Android默認是RSA 
     * /None/NoPadding】 
     *  
     * @param modulus 
     *            模 
     * @param exponent 
     *            指數 
     * @return 
     */  
    public static RSAPublicKey getPublicKey(String modulus, String exponent) {  
        try {  
            BigInteger b1 = new BigInteger(modulus);  
            BigInteger b2 = new BigInteger(exponent);  
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);  
            return (RSAPublicKey) keyFactory.generatePublic(keySpec);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  

    /** 
     * 使用模和指數生成RSA私鑰 
     * 注意:【此代碼用了默認補位方式,爲RSA/None/PKCS1Padding,不同JDK默認的補位方式可能不同,如Android默認是RSA 
     * /None/NoPadding】 
     *  
     * @param modulus 
     *            模 
     * @param exponent 
     *            指數 
     * @return 
     */  
    public static RSAPrivateKey getPrivateKey(String modulus, String exponent) {  
        try {  
            BigInteger b1 = new BigInteger(modulus);  
            BigInteger b2 = new BigInteger(exponent);  
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
            RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2);  
            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  

    /** 
     * 公鑰加密 
     *  
     * @param data 
     * @param publicKey 
     * @return 
     * @throws Exception 
     */  
    public static String encryptByPublicKey(String data, RSAPublicKey publicKey)  
            throws Exception {  
        Cipher cipher = Cipher.getInstance("RSA");  
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
        // 模長  
        int key_len = publicKey.getModulus().bitLength() / 8;  
        // 加密數據長度 <= 模長-11  
        String[] datas = splitString(data, key_len - 11);  
        String mi = "";  
        //如果明文長度大於模長-11則要分組加密  
        for (String s : datas) {  
            mi += bcd2Str(cipher.doFinal(s.getBytes()));  
        }  
        return mi;  
    }  

    /** 
     * 私鑰解密 
     *  
     * @param data 
     * @param privateKey 
     * @return 
     * @throws Exception 
     */  
    public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey)  
            throws Exception {  
        Cipher cipher = Cipher.getInstance("RSA");  
        cipher.init(Cipher.DECRYPT_MODE, privateKey);  
        //模長  
        int key_len = privateKey.getModulus().bitLength() / 8;  
        byte[] bytes = data.getBytes();  
        byte[] bcd = ASCII_To_BCD(bytes, bytes.length);  
        System.err.println(bcd.length);  
        //如果密文長度大於模長則要分組解密  
        String ming = "";  
        byte[][] arrays = splitArray(bcd, key_len);  
        for(byte[] arr : arrays){  
            ming += new String(cipher.doFinal(arr));  
        }  
        return ming;  
    }  
    /** 
     * ASCII碼轉BCD碼 
     *  
     */  
    public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) {  
        byte[] bcd = new byte[asc_len / 2];  
        int j = 0;  
        for (int i = 0; i < (asc_len + 1) / 2; i++) {  
            bcd[i] = asc_to_bcd(ascii[j++]);  
            bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i] << 4));  
        }  
        return bcd;  
    }  
    public static byte asc_to_bcd(byte asc) {  
        byte bcd;  

        if ((asc >= '0') && (asc <= '9'))  
            bcd = (byte) (asc - '0');  
        else if ((asc >= 'A') && (asc <= 'F'))  
            bcd = (byte) (asc - 'A' + 10);  
        else if ((asc >= 'a') && (asc <= 'f'))  
            bcd = (byte) (asc - 'a' + 10);  
        else  
            bcd = (byte) (asc - 48);  
        return bcd;  
    }  
    /** 
     * BCD轉字符串 
     */  
    public static String bcd2Str(byte[] bytes) {  
        char temp[] = new char[bytes.length * 2], val;  

        for (int i = 0; i < bytes.length; i++) {  
            val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);  
            temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');  

            val = (char) (bytes[i] & 0x0f);  
            temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');  
        }  
        return new String(temp);  
    }  
    /** 
     * 拆分字符串 
     */  
    public static String[] splitString(String string, int len) {  
        int x = string.length() / len;  
        int y = string.length() % len;  
        int z = 0;  
        if (y != 0) {  
            z = 1;  
        }  
        String[] strings = new String[x + z];  
        String str = "";  
        for (int i=0; i<x+z; i++) {  
            if (i==x+z-1 && y!=0) {  
                str = string.substring(i*len, i*len+y);  
            }else{  
                str = string.substring(i*len, i*len+len);  
            }  
            strings[i] = str;  
        }  
        return strings;  
    }  
    /** 
     *拆分數組  
     */  
    public static byte[][] splitArray(byte[] data,int len){  
        int x = data.length / len;  
        int y = data.length % len;  
        int z = 0;  
        if(y!=0){  
            z = 1;  
        }  
        byte[][] arrays = new byte[x+z][];  
        byte[] arr;  
        for(int i=0; i<x+z; i++){  
            arr = new byte[len];  
            if(i==x+z-1 && y!=0){  
                System.arraycopy(data, i*len, arr, 0, y);  
            }else{  
                System.arraycopy(data, i*len, arr, 0, len);  
            }  
            arrays[i] = arr;  
        }  
        return arrays;  
    }  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章