天天看點

密碼學之常見加密方式(02)三、DES解密

三、DES解密

idea中使用 ctrl + alt + m 快捷鍵抽取代碼

package com.atguigu.desaes;

import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
 * @author JsonHao😋
 * @date 2020年9月11日 下午9:22:52
 */
public class DesDemo {
    // DES加密算法,key的大小必須是8個位元組

    public static void main(String[] args) throws Exception {
        String input ="矽谷";
        // DES加密算法,key的大小必須是8個位元組
        String key = "12345678";

        String transformation = "DES"; // 9PQXVUIhaaQ=
        // 指定擷取密鑰的算法
        String algorithm = "DES";
        String encryptDES = encryptDES(input, key, transformation, algorithm);
        System.out.println("加密:" + encryptDES);
        String s = decryptDES(encryptDES, key, transformation, algorithm);
        System.out.println("解密:" + s);

    }

    /**
     * 使用DES加密資料
     *
     * @param input          : 原文
     * @param key            : 密鑰(DES,密鑰的長度必須是8個位元組)
     * @param transformation : 擷取Cipher對象的算法
     * @param algorithm      : 擷取密鑰的算法
     * @return : 密文
      * @throws Exception
      */
    private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 擷取加密對象
        Cipher cipher = Cipher.getInstance(transformation);
        // 建立加密規則
        // 第一個參數key的位元組
        // 第二個參數表示加密算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // ENCRYPT_MODE:加密模式
        // DECRYPT_MODE: 解密模式
        // 初始化加密模式和算法
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 加密
        byte[] bytes = cipher.doFinal(input.getBytes());

        // 輸出加密後的資料
        String encode = Base64.encode(bytes);

         return encode;
     }

    /**
     * 使用DES解密
     *
     * @param input          : 密文
     * @param key            : 密鑰
     * @param transformation : 擷取Cipher對象的算法
     * @param algorithm      : 擷取密鑰的算法
     * @throws Exception
     * @return: 原文
     */
    private static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 1,擷取Cipher對象
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定密鑰規則
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        cipher.init(Cipher.DECRYPT_MODE, sks);
        // 3. 解密,上面使用的base64編碼,下面直接用密文
        byte[] bytes = cipher.doFinal(Base64.decode(input));
        //  因為是明文,是以直接傳回
        return new String(bytes);
    }
}


      

四、base64補等号測試

package com.atguigu;
import com.sun.org.apache.xml.internal.security.utils.Base64;


/**
 * @author JsonHao😋
 * @date 2020年9月11日 下午9:30:20
 */
public class TestBase64 {
    public static void main(String[] args) {
        //  1:MQ== 表示一個位元組,不夠三個位元組,是以需要後面通過 == 号補齊
        System.out.println(Base64.encode("1".getBytes()));
        System.out.println(Base64.encode("12".getBytes()));
        System.out.println(Base64.encode("123".getBytes()));
//        // 矽谷:中文占6個位元組,6 * 8 = 48 ,剛剛好被整除,是以沒有等号
        System.out.println(Base64.encode("矽谷".getBytes()));
    }
}


      

五、AES加密解密

AES 加密解密和 DES 加密解密代碼一樣,隻需要修改加密算法就行,拷貝 ESC 代碼

package com.atguigu.desaes;
import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * @author JsonHao😋
 * @date 2020年9月11日 下午9:34:48
 */
public class AesDemo {
    // DES加密算法,key的大小必須是8個位元組

    public static void main(String[] args) throws Exception {
        String input ="矽谷";
        // AES加密算法,比較進階,是以key的大小必須是16個位元組
        String key = "1234567812345678";

        String transformation = "AES"; // 9PQXVUIhaaQ=
        // 指定擷取密鑰的算法
        String algorithm = "AES";
        // 先測試加密,然後在測試解密
        String encryptDES = encryptDES(input, key, transformation, algorithm);
        System.out.println("加密:" + encryptDES);
        String s = dncryptDES(encryptDES, key, transformation, algorithm);
        System.out.println("解密:" + s);

    }

    /**
     * 使用DES加密資料
     *
     * @param input          : 原文
     * @param key            : 密鑰(DES,密鑰的長度必須是8個位元組)
     * @param transformation : 擷取Cipher對象的算法
     * @param algorithm      : 擷取密鑰的算法
     * @return : 密文
     * @throws Exception
     */
    private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 擷取加密對象
        Cipher cipher = Cipher.getInstance(transformation);
        // 建立加密規則
        // 第一個參數key的位元組
        // 第二個參數表示加密算法
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        // ENCRYPT_MODE:加密模式
        // DECRYPT_MODE: 解密模式
        // 初始化加密模式和算法
        cipher.init(Cipher.ENCRYPT_MODE,sks);
        // 加密
        byte[] bytes = cipher.doFinal(input.getBytes());

        // 輸出加密後的資料
        String encode = Base64.encode(bytes);

        return encode;
    }

    /**
     * 使用DES解密
     *
     * @param input          : 密文
     * @param key            : 密鑰
     * @param transformation : 擷取Cipher對象的算法
     * @param algorithm      : 擷取密鑰的算法
     * @throws Exception
     * @return: 原文
     */
    private static String dncryptDES(String input, String key, String transformation, String algorithm) throws Exception {
        // 1,擷取Cipher對象
        Cipher cipher = Cipher.getInstance(transformation);
        // 指定密鑰規則
        SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
        cipher.init(Cipher.DECRYPT_MODE, sks);
        // 3. 解密
        byte[] bytes = cipher.doFinal(Base64.decode(input));

        return new String(bytes);
    }
}


      

運作結果是

MM#WLAN#Uc+9lGbR6e5N9hrtm7CA+A==#646465698#399900003000

[B@1540e19d

      

哪一個是正确的?為什麼?

這裡應該用new String()的方法,因為Base64加解密是一種轉換編碼格式的原理

toString()與new String ()用法差別

str.toString是調用了這個object對象的類的toString方法。一般是傳回這麼一個String:[class name]@[hashCode]

new String(str)是根據parameter是一個位元組數組,使用java虛拟機預設的編碼格式,将這個位元組數組decode為對應的字元。若虛拟機預設的編碼格式是ISO-8859-1,按照ascii編碼表即可得到位元組對應的字元。

什麼時候用什麼方法呢?

new String()一般使用字元轉碼的時候,byte[]數組的時候

toString()對象列印的時候使用