加密算法--->對稱加密與非對稱加密算舉例說明


目前主流的加密方式有:(對稱加密)AES、DES        (非對稱加密)RSA、DSA

 對稱加密例子:des對稱加密

des對稱加密,對稱加密,是一種比較傳統的加密方式,其加密運算、解密運算使用的是同樣的密鑰,信息的發送者和信息的接收者在進行信息的傳輸與處理時,必須共同持有該密碼(稱為對稱密碼),是一種對稱加密方式。

package me.andpay.ac.common.srv.idtag.bypay.util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.security.Key;

/**
 * @author wch
 */
public class DesUtil {
    /**
     * 密鑰算法
     * @version 1.0
     * @author
     */
    public static final String KEY_ALGORITHM = "DESede";

    /**
     * 加密/解密算法/工作模式/填充方式
     * @version 1.0
     * @author
     */
    public static final String CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding";

    /**
     * 轉換密鑰
     * @param key 二進制密鑰
     * @return key 密鑰
     *
     */
    public static Key toKey(byte[] key) throws Exception{
        //實例化DES密鑰材料
        DESedeKeySpec dks = new DESedeKeySpec(key);
        //實例化秘密密鑰工廠
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
        //生成秘密密鑰
        return keyFactory.generateSecret(dks);
    }

    /**
     * 解密
     * @param data 待解密數據
     * @param key 密鑰
     * @return byte[] 解密數據
     */
    public static byte[] decrypt(byte[] data, byte[] key)throws Exception{
        //還原密鑰
        Key k = toKey(key);
        /**
         * 實例化
         * 使用PKCS7Padding填充方式,按如下代碼實現
         * Cipher.getInstance(CIPHER_ALGORITHM,"BC");
         */
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        //初始化,設置為解密模式
        cipher.init(Cipher.DECRYPT_MODE, k);
        //執行操作
        return cipher.doFinal(data);
    }

    public static byte[] encrypt(byte[] data, byte[] key) throws Exception{
        //還原密鑰
        Key k = toKey(key);
        /**
         * 實例化
         * 使用PKCS7Padding填充方式,按如下代碼實現
         * Cipher.getInstance(CIPHER_ALGORITHM,"BC");
         */
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        //初始化,設置為解密模式
        //cipher.init(Cipher.ENCRYPT_MODE, k);
        cipher.init(Cipher.ENCRYPT_MODE,  k);

        //執行操作
        return cipher.doFinal(data);
    }

    /**
     * 生成密鑰
     *
     * @return byte[] 二進制密鑰
     */
    public static byte[] initKey() throws Exception{
        /**
         * 實例化
         * 使用128位或192位長度密鑰
         * KeyGenerator.getInstance(KEY_ALGORITHM,"BC");
         */
        KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
        /**
         * 初始化
         *使用128位或192位長度密鑰,按如下代碼實現
         *kg.init(128);
         *kg.init(192);
         */
        kg.init(168);
        //生成秘密密鑰
        SecretKey secretKey = kg.generateKey();
        //獲得密鑰的二進制編碼形式
        return secretKey.getEncoded();
    }

    //10進制數組轉換16進制數組
    public static String printbytes(String tip, byte[] b) {
        String ret = "";
        String str;
        for (int i = 0; i < b.length; i++) {

            str = Integer.toHexString((int) (b[i] & 0xff));

            if (str.length() == 1)
                str = "0" + str;
            ret = ret + str + " ";
        }

        // 02 00 07 00 00 60 70 01 17 35 03 C8
        return ret;
    }
}
des對稱加密工具欄

對稱加密例子:aes對稱加密

Aes加密解密方法使用Hex進行了編碼解碼

[java] view plain copy
package com.baidu.wallet.bdwallet.utils;  
import java.io.UnsupportedEncodingException;    
import java.security.InvalidKeyException;    
import java.security.NoSuchAlgorithmException;    
import javax.crypto.BadPaddingException;    
import javax.crypto.Cipher;    
import javax.crypto.IllegalBlockSizeException;    
import javax.crypto.NoSuchPaddingException;    
import javax.crypto.spec.SecretKeySpec;   
import org.apache.commons.codec.DecoderException;  
import org.apache.commons.codec.binary.Hex;  
public class Test {  
     private  static final String AES="AES";    
     private  static final String UTF8="UTF-8";    
          
       /** 
        * AES加密 
        * @param content 
        * @param pkey 
        * @return 
        * @throws DecoderException 
        */  
        private static byte[] encrypt(String content, String pkey) throws DecoderException {    
            try {    
                String private_key=pkey;  
                byte[] encodeFormat=null;  
                try {  
                    //秘鑰 Hex解碼為什么秘鑰要進行解碼,因為秘鑰是某個秘鑰明文進行了Hex編碼后的值,所以在使用的時候要進行解碼  
                    encodeFormat = Hex.decodeHex(private_key.toCharArray());  
                } catch (DecoderException e) {  
                    e.printStackTrace();  
                }  
                SecretKeySpec key = new SecretKeySpec(encodeFormat, AES);    
                // Cipher對象實際完成加密操作    
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");      
                // 加密內容進行編碼    
                byte[] byteContent = content.getBytes(UTF8);    
                // 用密匙初始化Cipher對象    
                cipher.init(Cipher.ENCRYPT_MODE, key);   
                // 正式執行加密操作    
                byte[] result = cipher.doFinal(byteContent);    
                return result;    
            } catch (NoSuchAlgorithmException e) {    
                e.printStackTrace();    
            } catch (NoSuchPaddingException e) {    
                e.printStackTrace();    
            } catch (InvalidKeyException e) {    
                e.printStackTrace();    
            } catch (UnsupportedEncodingException e) {    
                e.printStackTrace();    
            } catch (IllegalBlockSizeException e) {    
                e.printStackTrace();    
            } catch (BadPaddingException e) {    
                e.printStackTrace();    
            }    
            return null;    
        }    
        
        /** 
         * AES解密 
         * @param contents 
         * @param password 
         * @return 
         * @throws DecoderException 
         */  
        private static byte[] decrypt(String contents, String password) throws DecoderException {    
            try {   
                //密文使用Hex解碼  
                byte[]content = Hex.decodeHex(contents.toCharArray());    
                //秘鑰 Hex解碼為什么秘鑰要進行解碼,因為秘鑰是某個秘鑰明文進行了Hex編碼后的值,所以在使用的時候要進行解碼  
                byte[] encodeFormat = Hex.decodeHex(password.toCharArray());   
                SecretKeySpec key = new SecretKeySpec(encodeFormat, AES);    
                // Cipher對象實際完成加密操作    
                Cipher cipher = Cipher.getInstance(AES);    
                // 用密匙初始化Cipher對象    
                cipher.init(Cipher.DECRYPT_MODE, key);    
                // 正式執行解密操作    
                byte[] result = cipher.doFinal(content);    
                return result;    
            } catch (NoSuchAlgorithmException e) {    
                e.printStackTrace();    
            } catch (NoSuchPaddingException e) {    
                e.printStackTrace();    
            } catch (InvalidKeyException e) {    
                e.printStackTrace();    
            } catch (IllegalBlockSizeException e) {    
                e.printStackTrace();    
            } catch (BadPaddingException e) {    
                e.printStackTrace();    
            }    
            return null;    
        }    
        
        /** 
         * Aes加密 
         * @param context 明文 
         * @param private_key 秘鑰 
         * @return  
         * @throws DecoderException 
         */  
       public static String  encryption(String context,String private_key) throws DecoderException{  
           //加密后的明文也就變成了密文  
           byte[] encryptResult = encrypt(context, private_key);    
           //密碼文Hex編碼  
           String encryptResultStr = Hex.encodeHexString(encryptResult);  
           return encryptResultStr;  
       }  
         
       /** 
        * Aes解密 
        * @param context 密文 
        * @param private_key 秘鑰 
        * @return 
        * @throws DecoderException 
        * @throws UnsupportedEncodingException 
        */  
       public static String decryption(String context,String private_key) throws DecoderException, UnsupportedEncodingException{  
          //這里的密文解密前先進行了Hex解碼  
           byte[] decryptResult = decrypt(context, private_key);   
           String result = new String(decryptResult, UTF8);   
           return result;  
       }  
        
        
        public static void main(String[] args) throws UnsupportedEncodingException, DecoderException {   
            //加密內容  
            String content = "123456787654321";    
            //AES加密解密秘鑰  
            String password = "這個值一般都是給定的,雙發都知道";  
            // 加密    
            System.out.println("加密前:" + content);    
            // 調用加密方法  
            String encryptResultStr = encryption(content, password);    
            System.out.println("加密后:" + encryptResultStr);    
            // 調用解密方法  
            String result  = decryption(encryptResultStr, password);    
            // 解密內容進行解碼    
            System.out.println("解密后:" + result);    
        }    
}  
這個方法在正式的項目中已經在使用木有問題,注意這里的AES加密解密你要要對哦……
上面使用的就是org.apache.commons.codec.binary.Hex這個類的方法,在maven中配置如下:

[html] view plain copy
<dependency>    
            <groupId>commons-codec</groupId>    
            <artifactId>commons-codec</artifactId>    
            <version>1.4</version>    
        </dependency>    
注意:這里要使用1.4以及以上版本,應為1.4以下的沒有Hex.encodeHexString(byte[])這個方法!
aes對稱加密
Java使用AES加解密

目錄

1.1生成密鑰

1.2密鑰的存儲

1.3獲取存儲的密鑰

1.4加解密

1.5使用存儲的密鑰進行加解密示例

 

AES是一種對稱的加密算法,可基於相同的密鑰進行加密和解密。Java采用AES算法進行加解密的邏輯大致如下:

1、生成/獲取密鑰

2、加/解密

 

1.1生成密鑰
密鑰的生成是通過KeyGenerator來生成的。通過獲取一個KeyGenerator實例,然后調用其generateKey()方法即可生成一個SecretKey對象。大致邏輯一般如下:

 


private SecretKey geneKey() throws Exception {  
    //獲取一個密鑰生成器實例  
    KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);  
    SecureRandom random = new SecureRandom();  
    random.setSeed("123456".getBytes());//設置加密用的種子,密鑰  
    keyGenerator.init(random);  
    SecretKey secretKey = keyGenerator.generateKey();  
    return secretKey;  
}  
 

 

上述生成密鑰的過程中指定了固定的種子,每次生成出來的密鑰都是一樣的。還有一種形式,我們可以通過不指定SecureRandom對象的種子,即不調用其setSeed方法,這樣每次生成出來的密鑰都可能是不一樣的。


private SecretKey geneKey() throws Exception {  
    //獲取一個密鑰生成器實例  
    KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);  
    SecureRandom random = new SecureRandom();  
    keyGenerator.init(random);  
    SecretKey secretKey = keyGenerator.generateKey();  
    return secretKey;  
}  
 

 

通過KeyGenerator的init(keySize)方法進行初始化,而不是通過傳遞SecureRandom對象進行初始化也可以達到上面的效果,每次生成的密鑰都可能是不一樣的。但是對應的keySize的指定一定要正確,AES算法的keySize是128。


private SecretKey geneKey() throws Exception {  
    //獲取一個密鑰生成器實例  
    KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);  
    keyGenerator.init(128);  
    SecretKey secretKey = keyGenerator.generateKey();  
    return secretKey;  
}  
 

 

但是這種每次生成出來的密鑰都是不同的情況下,我們需要把加密用的密鑰存儲起來,以供解密的時候使用,不然就沒法進行解密了。

 

1.2密鑰的存儲
密鑰SecretKey里面最核心的內容就是其中的密鑰對應的字節數組,可以通過SecretKey的getEncoded()方法獲取。然后把它存儲起來即可。最簡單的方式就是直接寫入一個文件中。


//把上面的密鑰存起來  
Path keyPath = Paths.get("D:/aes.key");  
Files.write(keyPath, secretKey.getEncoded());  
 

 

1.3獲取存儲的密鑰
獲取存儲的密鑰的核心是把密鑰的字節數組轉換為對應的SecretKey。這可以通過SecretKeySpec來獲取,其實現了SecretKey接口,然后構造參數里面將接收密鑰的字節數組。


private SecretKey readKey(Path keyPath) throws Exception {  
    //讀取存起來的密鑰  
    byte[] keyBytes = Files.readAllBytes(keyPath);  
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);  
    return keySpec;  
}  
 

 

1.4加解密
Java采用AES算法進行加解密的過程是類似的,具體如下:

1、指定算法,獲取一個Cipher實例對象


Cipher cipher = Cipher.getInstance(ALGORITHM);//算法是AES  
 

2、生成/讀取用於加解密的密鑰


SecretKey secretKey = this.geneKey();  
 

3、用指定的密鑰初始化Cipher對象,同時指定加解密模式,是加密模式還是解密模式。


cipher.init(Cipher.ENCRYPT_MODE, secretKey);  
 

4、通過update指定需要加密的內容,不可多次調用。


cipher.update(content.getBytes());  
 

5、通過Cipher的dofinal()進行最終的加解密操作。


byte[] result = cipher.doFinal();//加密后的字節數組  
 

通過以上幾步就完成了使用AES算法進行加解密的操作了。其實第4、5步是可以合在一起的,即在進行doFinal的時候傳遞需要進行加解密的內容。但是如果update指定了加密的內容,而doFinal的時候也指定了加密的內容,那最終加密出來的結果將是兩次指定的加密內容的和對應的加密結果。


byte[] result = cipher.doFinal(content.getBytes());  
 

以下是一次加解密操作的完整示例。


public class AESTest {  
  
    private static final String ALGORITHM = "AES";  
      
    /** 
     * 生成密鑰 
     * @return 
     * @throws Exception 
     */  
    private SecretKey geneKey() throws Exception {  
        //獲取一個密鑰生成器實例  
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);  
        SecureRandom random = new SecureRandom();  
        random.setSeed("123456".getBytes());//設置加密用的種子,密鑰  
        keyGenerator.init(random);  
        SecretKey secretKey = keyGenerator.generateKey();  
        //把上面的密鑰存起來  
        Path keyPath = Paths.get("D:/aes.key");  
        Files.write(keyPath, secretKey.getEncoded());  
        return secretKey;  
    }  
      
    /** 
     * 讀取存儲的密鑰 
     * @param keyPath 
     * @return 
     * @throws Exception 
     */  
    private SecretKey readKey(Path keyPath) throws Exception {  
        //讀取存起來的密鑰  
        byte[] keyBytes = Files.readAllBytes(keyPath);  
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, ALGORITHM);  
        return keySpec;  
    }  
      
    /** 
     * 加密測試 
     */  
    @Test  
    public void testEncrypt() throws Exception {  
        //1、指定算法、獲取Cipher對象  
        Cipher cipher = Cipher.getInstance(ALGORITHM);//算法是AES  
        //2、生成/讀取用於加解密的密鑰  
        SecretKey secretKey = this.geneKey();  
        //3、用指定的密鑰初始化Cipher對象,指定是加密模式,還是解密模式  
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);  
        String content = "Hello AES";//需要加密的內容  
        //4、更新需要加密的內容  
        cipher.update(content.getBytes());  
        //5、進行最終的加解密操作  
        byte[] result = cipher.doFinal();//加密后的字節數組  
        //也可以把4、5步組合到一起,但是如果保留了4步,同時又是如下這樣使用的話,加密的內容將是之前update傳遞的內容和doFinal傳遞的內容的和。  
//      byte[] result = cipher.doFinal(content.getBytes());  
        String base64Result = Base64.getEncoder().encodeToString(result);//對加密后的字節數組進行Base64編碼  
        System.out.println("Result: " + base64Result);  
    }  
      
    /** 
     * 解密測試 
     */  
    @Test  
    public void testDecrpyt() throws Exception {  
        Cipher cipher = Cipher.getInstance(ALGORITHM);  
        SecretKey secretKey = this.geneKey();  
        cipher.init(Cipher.DECRYPT_MODE, secretKey);  
        String content = "pK9Xw4zqTMXYraDadSGJE3x/ftrDxIg2AM/acq0uixA=";//經過Base64加密的待解密的內容  
        byte[] encodedBytes = Base64.getDecoder().decode(content.getBytes());  
        byte[] result = cipher.doFinal(encodedBytes);//對加密后的字節數組進行解密  
        System.out.println("Result: " + new String(result));  
    }  
      
}  
 

1.5使用存儲的密鑰進行加解密示例

@Test  
public void test() throws Exception {  
    Cipher cipher = Cipher.getInstance(ALGORITHM);  
    KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);  
    keyGenerator.init(128);  
    SecretKey secretKey = keyGenerator.generateKey();  
    //把上面的密鑰存起來  
    Path keyPath = Paths.get("D:/aes.key");  
    Files.write(keyPath, secretKey.getEncoded());  
      
    //讀取存起來的密鑰  
    SecretKey key = this.readKey(keyPath);  
    cipher.init(Cipher.ENCRYPT_MODE, key);  
    cipher.update("Hello World".getBytes());  
    //密文  
    byte[] encryptBytes = cipher.doFinal();  
    System.out.println(Base64.getEncoder().encodeToString(encryptBytes));  
      
    //用取出來的密鑰進行解密  
    cipher.init(Cipher.DECRYPT_MODE, key);  
    //明文  
    byte[] decryptBytes = cipher.doFinal(encryptBytes);  
    System.out.println(new String(decryptBytes));  
}  
 

在上面的示例中,我們先生成了一個密鑰,然后把它保存到本地文件中,然后再把它讀出來,分別用以加密和解密。而且我們加密和解密都是用的同一個Cipher對象,但是在使用前需要重新通過init方法初始化加解密模式。
aes的總結

非對稱加密例子:RSA非對稱加密

流程如下:


秘鑰生成工具類

package com.test;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import sun.misc.BASE64Encoder;

public class RSAKEYUtil {

    /** 指定加密算法為RSA */
    private static final String ALGORITHM = "RSA";
    /** 密鑰長度,用來初始化 */
    private static final int KEYSIZE = 1024;
    /** 指定公鑰存放文件 */
    private static String PUBLIC_KEY_FILE = "PublicKey";
    /** 指定私鑰存放文件 */
    private static String PRIVATE_KEY_FILE = "PrivateKey";

    public static void main(String[] args) throws Exception {
        generateKeyPair();
        genKeyPair();
    }

    /**
    * 生成密鑰對
    * @throws Exception
    */
    private static void generateKeyPair() throws Exception {

        //     /** RSA算法要求有一個可信任的隨機數源 */
        //     SecureRandom secureRandom = new SecureRandom();
        /** 為RSA算法創建一個KeyPairGenerator對象 */
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);

        /** 利用上面的隨機數據源初始化這個KeyPairGenerator對象 */
        //     keyPairGenerator.initialize(KEYSIZE, secureRandom);
        keyPairGenerator.initialize(KEYSIZE);

        /** 生成密匙對 */
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        /** 得到公鑰 */
        Key publicKey = keyPair.getPublic();

        /** 得到私鑰 */
        Key privateKey = keyPair.getPrivate();

        ObjectOutputStream oos1 = null;
        ObjectOutputStream oos2 = null;
        try {
            /** 用對象流將生成的密鑰寫入文件 */
            oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));
            oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));
            oos1.writeObject(publicKey);
            oos2.writeObject(privateKey);
        } catch (Exception e) {
            throw e;
        } finally {
            /** 清空緩存,關閉文件輸出流 */
            oos1.close();
            oos2.close();
        }
    }

    private static void genKeyPair() throws NoSuchAlgorithmException {
        
        /** RSA算法要求有一個可信任的隨機數源 */
        SecureRandom secureRandom = new SecureRandom();
        
        /** 為RSA算法創建一個KeyPairGenerator對象 */
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);

        /** 利用上面的隨機數據源初始化這個KeyPairGenerator對象 */
        keyPairGenerator.initialize(KEYSIZE, secureRandom);
        //keyPairGenerator.initialize(KEYSIZE);

        /** 生成密匙對 */
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        /** 得到公鑰 */
        Key publicKey = keyPair.getPublic();

        /** 得到私鑰 */
        Key privateKey = keyPair.getPrivate();

        byte[] publicKeyBytes = publicKey.getEncoded();
        byte[] privateKeyBytes = privateKey.getEncoded();

        String publicKeyBase64 = new BASE64Encoder().encode(publicKeyBytes);
        String privateKeyBase64 = new BASE64Encoder().encode(privateKeyBytes);

        System.out.println("publicKeyBase64.length():" + publicKeyBase64.length());
        System.out.println("publicKeyBase64:" + publicKeyBase64);

        System.out.println("privateKeyBase64.length():" + privateKeyBase64.length());
        System.out.println("privateKeyBase64:" + privateKeyBase64);
    }
}
公鑰和私鑰生成
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

import javax.crypto.Cipher;

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

public class RSAUtil {

    /** 指定加密算法為RSA */
    private static final String ALGORITHM = "RSA";
    /** 指定公鑰存放文件 */
    private static String PUBLIC_KEY_FILE = "PublicKey";
    /** 指定私鑰存放文件 */
    private static String PRIVATE_KEY_FILE = "PrivateKey";

    public static void main(String[] args) throws Exception {

        String source = "你好nihao";// 要加密的字符串
        System.out.println("准備用公鑰加密的字符串為:" + source);

        String cryptograph = encrypt(source);// 生成的密文
        System.out.print("用公鑰加密后的結果為:" + cryptograph);
        System.out.println();

        String target = decrypt(cryptograph);// 解密密文
        System.out.println("用私鑰解密后的字符串為:" + target);
        System.out.println();
    }

    /**
     * 加密方法
     * @param source 源數據
     * @return
     * @throws Exception
     */
    public static String encrypt(String source) throws Exception {

        Key publicKey = getKey(PUBLIC_KEY_FILE);

        /** 得到Cipher對象來實現對源數據的RSA加密 */
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] b = source.getBytes();
        /** 執行加密操作 */
        byte[] b1 = cipher.doFinal(b);
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(b1);
    }

    /**
     * 解密算法
     * @param cryptograph    密文
     * @return
     * @throws Exception
     */
    public static String decrypt(String cryptograph) throws Exception {

        Key privateKey = getKey(PRIVATE_KEY_FILE);

        /** 得到Cipher對象對已用公鑰加密的數據進行RSA解密 */
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] b1 = decoder.decodeBuffer(cryptograph);

        /** 執行解密操作 */
        byte[] b = cipher.doFinal(b1);
        return new String(b);
    }

    /**
     * 讀取文件轉化成key
     * @param fileName
     * @return
     * @throws Exception
     * @throws IOException
     */
    private static Key getKey(String fileName) throws Exception, IOException {
        Key key;
        ObjectInputStream ois = null;
        try {
            /** 將文件中的私鑰對象讀出 */
            ois = new ObjectInputStream(new FileInputStream(fileName));
            key = (Key) ois.readObject();
        } catch (Exception e) {
            throw e;
        } finally {
            ois.close();
        }
        return key;
    }


    /**
     * 轉化器 String 轉 PrivateKey實體
     * @param key
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(key);;
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }


    /**
     * Rsa解密
     * 解密算法
     * @param cryptograph    密文
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKey(byte[] cryptograph,String key) throws Exception {
        Key privateKey = getPrivateKey(key);
        /** 得到Cipher對象對已用公鑰加密的數據進行RSA解密 */
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(cipher.doFinal(cryptograph));
    }


}
加密解密過程
package me.andpay.ac.common.srv.idtag.bypay.util;

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

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * @author xiao bin
 */
public class RSACoder {
    public static final String KEY_ALGORITHM = "RSA";
    public static final String PUBLIC_KEY = "RSAPublicKey";
    public static final String PRIVATE_KEY = "RSAPrivateKey";

    private static final int KEY_SIZE = 512;

    // 私鑰解密
    public static byte[] decryptByPrivateKey(byte[] data, byte[] key)
            throws Exception {
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }
    // 私鑰解密2
    public static String decryptByPrivateKey(String data, String key)
            throws Exception {
        BASE64Decoder dec=new BASE64Decoder();
        byte[] dataByte=decryptByPrivateKey(dec.decodeBuffer(data),dec.decodeBuffer(key));
        return new String(dataByte);
    }
    // 公鑰解密
    public static byte[] decryptByPublicKey(byte[] data, byte[] key)
            throws Exception {
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);

        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);

        return cipher.doFinal(data);
    }
    // 公鑰解密2
    public static String decryptByPublicKey(String data, String key)
            throws Exception {
        BASE64Decoder dec=new BASE64Decoder();
        byte[] dataByte=decryptByPublicKey(dec.decodeBuffer(data),dec.decodeBuffer(key));
        return new String(dataByte);
    }
    // 公鑰加密
    public static byte[] encryptByPublicKey(byte[] data, byte[] key)
            throws Exception {
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
//      取摸和指數
//        System.out.println("publicKey:"+publicKey);
//        RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
//        System.out.println(rsaPublicKey.getModulus().toString());
//        System.out.println(rsaPublicKey.getPublicExponent().toString());
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }
    // 公鑰加密2
    public static String encryptByPublicKey(String data, String key)throws Exception {
        BASE64Decoder dec=new BASE64Decoder();
        BASE64Encoder enc=new BASE64Encoder();
        byte[] signByte=encryptByPublicKey(data.getBytes("utf-8"),dec.decodeBuffer(key));
        return enc.encode(signByte);
    }
    // 私鑰加密
    public static byte[] encryptByPrivateKey(byte[] data, byte[] key)
            throws Exception {
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }
    // 私鑰加密2
    public static String encryptByPrivateKey(String data, String key)
            throws Exception {
        BASE64Decoder dec=new BASE64Decoder();
        BASE64Encoder enc=new BASE64Encoder();
        byte[] signByte=encryptByPrivateKey(data.getBytes(),dec.decodeBuffer(key));
        return enc.encode(signByte);
    }

    //私鑰驗證公鑰密文
    public static boolean checkPublicEncrypt(String data,String sign,String pvKey)
            throws Exception{
        return data.equals(decryptByPrivateKey(sign,pvKey));
    }
    public static boolean checkPrivateEncrypt(String data,String sign,String pbKey)
            throws Exception{
        return data.equals(decryptByPublicKey(sign,pbKey));
    }
    //取得私鑰
    public static byte[]getPrivateKey(Map<String,Object> keyMap) throws Exception{
        Key key=(Key)keyMap.get(PRIVATE_KEY);
        return key.getEncoded();
    }
    //取得公鑰
    public static byte[]getPublicKey(Map<String,Object> keyMap) throws Exception{
        Key key=(Key)keyMap.get(PUBLIC_KEY);
        return key.getEncoded();
    }
    //初始化密鑰
    public static Map<String,Object> initKey() throws Exception{
        KeyPairGenerator keyPairGen =KeyPairGenerator.getInstance(KEY_ALGORITHM);

        keyPairGen.initialize(KEY_SIZE);

        KeyPair keyPair=keyPairGen.generateKeyPair();

        RSAPublicKey publicKey=(RSAPublicKey)keyPair.getPublic();
        RSAPrivateKey privateKey=(RSAPrivateKey)keyPair.getPrivate();

        Map<String,Object> keyMap =new HashMap<String,Object>(2);
        keyMap.put(PUBLIC_KEY,publicKey);
        keyMap.put(PRIVATE_KEY,privateKey);
        return keyMap;
    }
}
別人提供的工具類

 加密數據結構實體

// 加密報文體格式:BASE64(商戶號)| BASE64(RSA(報文加密密鑰))| BASE64(3DES(報文原文))
/**
* 生成秘鑰
* @return
*/
public byte[] genTDesKey(){
byte[] key = UUID.randomUUID().toString().getBytes();
return key;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM