2018年10月14日 星期日

【Java】使用Cipher實現字串加密/解密



程式碼:CipherAdaptor.java
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherSpi;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class CipherAdaptor{
private Base64.Decoder decoder=Base64.getDecoder();
private Base64.Encoder encoder=Base64.getEncoder();
    private final SecretKey secretKey;
    private final String algorithm,charset;
    private Cipher cipher;
    CipherAdaptor(String algorithm,SecretKey secretKey,String charset) throws NoSuchPaddingException, NoSuchAlgorithmException {
    encoder=encoder.withoutPadding();//設定Base64的解碼規則:編碼器省略末段的'='字符(如果有的話)。
    this.secretKey=secretKey;
        this.algorithm=algorithm;
        this.charset=charset;
        cipher=Cipher.getInstance(algorithm);//定義Cipher所使用的演算法
     
    }
/*
 * 明文:訊息
 * 密文:明文經過加密所產生的信息被稱為密文
 *
 */
    String encrypt(String str) throws Exception {
//    將明文轉換成位元組陣列
        byte[] executed=encrypt(str.getBytes(charset));
     
//    將已加密的位元組陣列使用Base64表示,因為輸出的位元組值不一定在字碼表內,
//        Base64可以將原始資料轉換為字串,提供後續使用的方便性。
        return encoder.encodeToString(executed);
    }

    byte[] encrypt(byte[] raw) throws Exception {
//    將位元組陣列編碼成Base64格式
        return execute(raw,Cipher.ENCRYPT_MODE,secretKey);
    }

    String decrypt(String str) throws Exception {
//    將密文解碼成位元組陣列
        byte[] CryptedBytes=decoder.decode(str);
     
        return new String(decrypt(CryptedBytes),charset);
    }

    byte[] decrypt(byte[] raw) throws Exception {
//    將已加密的位元組解密成位元組
        return execute(raw,Cipher.DECRYPT_MODE,secretKey);
    }

    String getAlgorithm(){
        return cipher.getAlgorithm();
    }

    private byte[] execute(byte[] raw,int mode,SecretKey secretKey) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException{
        cipher.init(mode,secretKey);//初始化Cipher
        return cipher.doFinal(raw);//加密(Cipher.ENCRYPT_MODE)/解密(DECRYPT_MODE)
    }
 
    static SecretKey Str2Key(String str,String algorithm) throws UnsupportedEncodingException {
//    將字串轉換成位元組陣列
    byte[] byte_key=str.getBytes("UTF-8");
   
//    將位元組轉成SecretKey
        return new SecretKeySpec(byte_key,0,byte_key.length,algorithm);
    }
 

}


程式碼:AdaptorTest.java
import java.util.Scanner;

import javax.crypto.SecretKey;

public class AdaptorTest {
static Scanner src = new Scanner(System.in);

public static void main(String[] args) throws Exception {
System.out.print("KEY:");
String key = src.nextLine();
System.out.print("Algorithm:");
String algorithm = src.nextLine();

SecretKey secretKey = CipherAdaptor.Str2Key(key, algorithm);
CipherAdaptor ca = new CipherAdaptor(algorithm, secretKey, "UTF-8");

while (true) {
System.out.print("mode:");
String mode = src.nextLine();
if (mode.equals("x")) {
System.exit(0);
}

System.out.print("content:");
String contain = src.nextLine();

if (mode.equals("e")) {
System.out.println("encrypt:" + ca.encrypt(contain));
} else if (mode.equals("d")) {
System.out.println("decrypt:" + ca.decrypt(contain));
}
}
}
}



Console
KEY:12345678
Algorithm:DES
mode:e
content:Hello I am Vincent Yeh,my chinese name is 小明。
encrypt:q8aMK5vjOWnfAJB60Gh+4QTSPztjEwQcpCbrXF94xR6RmWQAEl6VpOykz6lt5Y8DJRV/XXVD6cU
mode:d
content:q8aMK5vjOWnfAJB60Gh+4QTSPztjEwQcpCbrXF94xR6RmWQAEl6VpOykz6lt5Y8DJRV/XXVD6cU
decrypt:Hello I am Vincent Yeh,my chinese name is 小明。
mode:x



參考資料

沒有留言:

張貼留言