1. 程式人生 > >java各種加密方法實現

java各種加密方法實現

一般來講,在java上實現加密解密演算法,有3種方式。

  1. 自行實現演算法、
  2. 使用java自帶的crypto軟體包
  3. 使用第三方庫

本文講述一下第二種使用方法。我最開始也是找了很多這方面的資料,但是總感覺還是缺乏一些細節。現將我的一些心得與大家分享。

本文給出的例子基於下面的blog中所給出的例子。

blog.csdn.net/wildandfly/article/details/21521857

首先,現代密碼學演算法大致可以分為3個大塊。分別是對稱加密symmetric,非對稱加密asymmetric,訊息摘要hash。

本文實現了下列的幾種演算法,其中每個package中的演算法都非常類似。
這裡寫圖片描述

不羅嗦,直接上程式碼

1對稱加密

以AES為例。注意其中keygenerator函式,其中keygenerator.getInstance()函式需要輸入對應的密碼方法,從而生成對應長度的key。

這裡,我查了下doc。可以傳入的引數如下圖。

這裡寫圖片描述

package com.zhicheng.cryptogram;

import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import
javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import com.alibaba.fastjson.JSONObject; /** * 根據指定的16位aes_key,對id進行加解密 * @author wb-zcf274530 * */ public class SymmetricEncryption { //金鑰生成支援16位字元 private static final String aes_key = "assistant7654321"; public
static String encrypt(long id) { byte[] key = Base64.decodeBase64(aes_key); byte[] input = String.valueOf(id).getBytes(); byte[] encryptBytes = Cryptos.aesEncrypt(input, key); return Base64.encodeBase64URLSafeString(encryptBytes); } public static Long decrypt(String securityId) { byte[] key = Base64.decodeBase64(aes_key); String value = Cryptos.aesDecrypt(Base64.decodeBase64(securityId), key); return Long.parseLong(value); } static class Cryptos{ private static final String AES = "AES"; public static byte[] aesEncrypt(byte[] input,byte[] key) { // ENCRYPT_MODE表示加密模式 return aes(input,key,Cipher.ENCRYPT_MODE); } public static String aesDecrypt(byte[] input,byte[] key) { // DECRYPT_MODE表示解密模式 byte[] decypt = aes(input,key,Cipher.DECRYPT_MODE); return new String(decypt); } private static byte[] aes(byte[] input,byte[] key,int mode) { try { //根據指定關鍵字進行獲取加密金鑰 SecretKey secretKey = new SecretKeySpec(key, AES); //例項化支援AES演算法的金鑰生成器(演算法名稱命名需按規定,否則丟擲異常) Cipher cipher = Cipher.getInstance(AES); //根據金鑰,對Cipher物件進行初始化 cipher.init(mode, secretKey); return cipher.doFinal(input); }catch(Exception e) { throw unchecked(e); } } /** * 生成金鑰 * @return */ public static String generateKey() { KeyGenerator keygen = null; try { keygen = KeyGenerator.getInstance("AES"); } catch (NoSuchAlgorithmException e) { } //SecretKey 負責儲存對稱金鑰 SecretKey deskey = keygen.generateKey(); return Base64.encodeBase64String(deskey.getEncoded()); } /** * 將CheckedException轉換為UncheckedException. */ private static RuntimeException unchecked(Exception e) { if (e instanceof RuntimeException) { return (RuntimeException) e; } else { return new RuntimeException(e); } } public static void main(String[] args) throws NoSuchAlgorithmException { /*String result = encrypt(1989L); System.out.println(result);; System.out.println("the encrypt:"+decrypt(result));*/ KeyGenerator keygen = KeyGenerator.getInstance("AES"); //SecretKey 負責儲存對稱金鑰 SecretKey deskey = keygen.generateKey(); System.out.println(Base64.encodeBase64String(deskey.getEncoded())); } } }

2非對稱加密

以rsa為例,由於公鑰加密體系需要2個key值,故產生key值的函式也發生了改變。

keypairgenerator.getInstance()函式同樣需要傳入加密的方法,產生對應的key值。

這裡,我也查了下doc,如下。
這裡寫圖片描述

package com.zhicheng.cryptogram;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

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

/**
 * 非對稱性加密(公私鑰加密)
 * 1、每次生成的公私鑰對都是不同的,所以要求對其進行儲存
 * @author wb-zcf274530
 *
 */
public class AsymmetricEncryption {

    private static final String RSA = "RSA";

     /** 
     * 加密 
     *  
     * @param publicKey 
     * @param srcBytes 
     * @return 
     * @throws NoSuchAlgorithmException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     * @throws IllegalBlockSizeException 
     * @throws BadPaddingException 
     */  
    public byte[] encrypt(String publicKey, byte[] srcBytes) throws NoSuchAlgorithmException,  
            NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {  
        try {
            if (publicKey != null) {  
                PublicKey key = getPublicKey(publicKey);
                 return rsa(key,srcBytes,Cipher.ENCRYPT_MODE);  
            }  
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;  
    }

    /**
     * 獲取公鑰
     * @param filename
     * @return
     * @throws Exception
     */
    private static PublicKey getPublicKey(String publicKey) throws Exception { 
        byte[] publicKeys = Base64.decodeBase64(publicKey);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeys); 
        KeyFactory kf = KeyFactory.getInstance(RSA);  
        return kf.generatePublic(spec); 
    } 

    /**
      * 獲取私鑰
      * @param filename
      * @return
      * @throws Exception
      */
     private static PrivateKey getPrivateKey(String privateKey)throws Exception { 
         byte[] keyBytes = Base64.decodeBase64(privateKey);
         PKCS8EncodedKeySpec spec =new PKCS8EncodedKeySpec(keyBytes); 
         KeyFactory kf = KeyFactory.getInstance(RSA); 
         return kf.generatePrivate(spec); 
       } 



    /** 
     * 解密 
     *  
     * @param privateKey 
     * @param srcBytes 
     * @return 
     * @throws NoSuchAlgorithmException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     * @throws IllegalBlockSizeException 
     * @throws BadPaddingException 
     */  
    public byte[] decrypt(String privateKey, byte[] srcBytes) throws NoSuchAlgorithmException,  
            NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {  
        try {
            if (privateKey != null) {  
                PrivateKey key = getPrivateKey(privateKey);
                // 根據公鑰,對Cipher物件進行初始化  
               return rsa(key,srcBytes,Cipher.DECRYPT_MODE); 
            } 
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;  
    }  

    public byte[] rsa(Key key,byte[] input,int mode) throws IllegalBlockSizeException, 
        BadPaddingException, InvalidKeyException, 
        NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance(RSA); 
        // 根據公鑰,對Cipher物件進行初始化  
        cipher.init(mode, key);  
        byte[] resultBytes = cipher.doFinal(input);  
        return resultBytes;  
    }
    /** 
     * @param args 
     * @throws NoSuchAlgorithmException 
     * @throws BadPaddingException 
     * @throws IllegalBlockSizeException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     */  
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException,  
            IllegalBlockSizeException, BadPaddingException {  
        AsymmetricEncryption rsa = new AsymmetricEncryption();  
        String msg = "www.suning.com/index.jsp";  
        // KeyPairGenerator類用於生成公鑰和私鑰對,基於RSA演算法生成物件  
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(RSA);  
        // 初始化金鑰對生成器,金鑰大小為1024位  
        keyPairGen.initialize(1024);  
        // 生成一個金鑰對,儲存在keyPair中  
        KeyPair keyPair = keyPairGen.generateKeyPair();  
        // 得到私鑰  
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
        // 得到公鑰  
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  

        // 用公鑰加密  
        byte[] srcBytes = msg.getBytes();  
        byte[] resultBytes = rsa.encrypt(Base64.encodeBase64String(publicKey.getEncoded()), srcBytes);  
        System.out.println(Base64.encodeBase64String(publicKey.getEncoded()));
        // 用私鑰解密  
        byte[] decBytes = rsa.decrypt(Base64.encodeBase64String(privateKey.getEncoded()), resultBytes);  
        System.out.println(Base64.encodeBase64String(privateKey.getEncoded()));
        System.out.println("明文是:" + msg);  
        System.out.println("加密後是:" + new String(resultBytes));  
        System.out.println("解密後是:" + new String(decBytes));  
    }  
}

3hash函式
這個由於我沒有用到,暫時就不寫了,以後再補上。

注意:

在1、2中除了keygenerator需要傳遞密碼的方法,cipher在初始化時也需要指定其引數。如下所示。
這裡寫圖片描述