對於加密解密的初步瞭解

GeneralAndroid發表於2017-12-06

由於工作任務的分配,最近把之前丟下的加密與解密的內容撿了起來,本篇博文不會涉及加密演算法的原理以及具體實現,有時間會深究其原理,這篇博文主要是對加密演算法的概括以及Java中常用加密演算法的使用。

加密演算法可以大致分為3類:對稱加密演算法、非對稱加密演算法、雜湊演算法。

對稱加密演算法:加密和解密使用相同金鑰的演算法,常見演算法:DES、3DES、AES等。

非對稱加密演算法:使用一對公私鑰來進行加密解密的演算法,一般公鑰加密,私鑰解密,公鑰可以隨意暴露,常見演算法:RSA、DSA等。

雜湊演算法:又稱為單向加密或不可逆加密,常見演算法:MD5、SHA等。

加密演算法的效能通常可以按照演算法本身的複雜程式、金鑰長度(金鑰越長越安全)、加解密速度等來衡量。

在實際的操作過程中,我們通常採用非對稱加密演算法來管理對稱演算法的金鑰,然後用對稱加密演算法來加密資料,這樣我們就集合了兩類加密演算法的優勢,既實現了加密速度快,又實現了安全方便管理金鑰的優點。

下面開始介紹幾個常用加密演算法的使用:

DES(Data Encryption Standard):即資料加密標準,是一種使用金鑰加密的塊演算法。使用姿勢請看下面程式碼:

package com.general.encryanddecode;
 
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.SecureRandom;
 
public class DESTest {
 
    private String oContent;
    private byte[] pContent;
    private SecretKey key;
 
    public DESTest(String oContent) {
 
        this.oContent = oContent;
        try {
 
            key = KeyGenerator.getInstance("DES").generateKey();
            System.out.println("金鑰:" + BytesToHex.fromBytesToHex(key.getEncoded()));
        } catch (Exception e) {
 
        }
    }
 
    public static void main(String[] args) {
 
        String key = "12345678";//金鑰最小為8位。
        String content = "GeneralAndroid->Android將軍";
        DESTest test = new DESTest(content);
        test.encrypt();
        test.decrypt();
    }
 
    public void encrypt() {
        try {
            SecureRandom secureRandom = new SecureRandom();
 
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, key, secureRandom);
            pContent = cipher.doFinal(oContent.getBytes());
            System.out.println("加密:" + BytesToHex.fromBytesToHex(pContent));
        } catch (Exception e) {
            e.printStackTrace();
 
        }
 
 
    }
 
    public void decrypt() {
        try {
            SecureRandom random = new SecureRandom();
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, key, random);
            System.out.println("解密:" + new String(cipher.doFinal(pContent)));
            ;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
}
/***
 *
 金鑰:54fbfb1aa2e6899b
 加密:47dcf9e97b51d855553d2478101fcbb85fd29b5da28f0a66f995f0ac179bff29
 解密:GeneralAndroid->Android將軍
 *
 *
 * **/
 
複製程式碼

3DES(Triple DES):是DES向AES過渡的加密演算法,它使用3條56位的金鑰對資料進行三次加密,是DES的一個更安全的變形。它以DES為基本模組,通過組合分組方法設計出分組加密演算法。比起最初的DES,3DES更為安全。

該方法使用兩個金鑰,執行三次DES演算法,加密的過程是加密-解密-加密,解密的過程是解密-加密-解密。 3DES加密過程為:C=Ek3(Dk2(Ek1(P))) 3DES解密過程為:P=Dk1(Ek2(Dk3(C))) 採用兩個金鑰進行三重加密的好處有: (1)兩個金鑰合起來有效金鑰長度有112bit,可以滿足商業應用的需要,若採用總長為168bit的三個金鑰,會產生不必要的開銷。 (2)加密時採用加密-解密-加密,而不是加密-加密-加密的形式,這樣有效的實現了與現有DES系統的向後相容問題。因為當K1=K2時,三重DES的效果就和原來的DES一樣,有助於逐漸推廣三重DES。 (3)三重DES具有足夠的安全性,目前還沒有關於攻破3DES的報導。

使用姿勢,和DES的程式碼塊差不多,將DES改為DESede即可。這裡就不貼程式碼了。 AES(Advanced Encryption Standard):高階加密標準,在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準,這個標準用來替換原來的DES。 使用姿勢,和DES的程式碼塊差不多,將DES改為AES即可。這裡就不貼程式碼了。 RSA:RSA同時有兩把鑰匙,公鑰與私鑰。同時支援數字簽名。數字簽名的意義在於,對傳輸過來的資料進行校驗。確保資料在傳輸工程中不被修改。其使用姿勢如下面程式碼所示:

package com.general.encryanddecode;
 
import javax.crypto.Cipher;
 
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
 
public class RSATest {
    private Key publicKey;
    private Key privateKey;
    private String oContent;
    private byte[] pContent;
 
    public RSATest(String oContent) {
        this.oContent = oContent;
        try{
            generateKeyPair();
        }catch (Exception e){
            e.printStackTrace();
        }
 
    }
 
    public void generateKeyPair() throws Exception {
 
        SecureRandom sr = new SecureRandom();
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024, sr);
        KeyPair kp = kpg.generateKeyPair();
        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();
        System.out.println("公鑰:" + BytesToHex.fromBytesToHex(publicKey.getEncoded()));
        System.out.println("私鑰:" + BytesToHex.fromBytesToHex(privateKey.getEncoded()));
 
    }
 
    public void encrypt() {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            pContent = cipher.doFinal(oContent.getBytes());
            System.out.println("密文:" + BytesToHex.fromBytesToHex(pContent));
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void decrypt(){
        try{
            Cipher cipher=Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE,privateKey);
            System.out.println("原文:"+new String(cipher.doFinal(pContent)));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] args){
        RSATest test=new RSATest("GeneralAndroid->Android將軍");
        test.encrypt();
        test.decrypt();
    }
 
 
}
/***
 *
 公鑰:30819f300d06092a864886f70d010101050003818d0030818902818100948b98bfcdcae77156ebd2e2d3dc7822295073c4326410edb50ab6737f2c594387eb2f0ab622211ac229a6f395bcb8b24653bebf90151895d9be951ee1dbdaa529b7951db529cee2aa3bf9cc52bfb5928b498333aaab8ee6bb4904d5afd387a2e09ddf8320258597948bfa6d4f7034bb76f7fbc80139bc0456c1a14190d054af0203010001
 私鑰:30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100948b98bfcdcae77156ebd2e2d3dc7822295073c4326410edb50ab6737f2c594387eb2f0ab622211ac229a6f395bcb8b24653bebf90151895d9be951ee1dbdaa529b7951db529cee2aa3bf9cc52bfb5928b498333aaab8ee6bb4904d5afd387a2e09ddf8320258597948bfa6d4f7034bb76f7fbc80139bc0456c1a14190d054af0203010001028180532087bb966b9cf745403544b070e95d9ca72411c06d5537e11f7c98c7ab46cccecc2308288292ea098c0b9cb6c7e4c80729284ec54fb8f16ae807453ff9abb1f55f3fb6684b595d94a45ef091f00d9a6b0146b8bcb2fc1c3cbd9c1218f65b204996e546817aa00769070042cacf67b4d0df6367821111953862386385904381024100cba0822bbd32ed3949c3f6c4c2ae1da16d453ad727a682a1bd451c5208232427b0a6202e44e10f7cb6c0967488773199891035e9de3cc76adefbec73378b9f6f024100bac052b6460c051f277b869b79883d5ebccfe971afd77b78536ef55a5c18cfef803f026fc624f2f4000404e53efd4b63ee2b4fcc3e388fe69093b3944ef3fec102402d50fe472fa6fac64a155380bc76b55f6c8b00aa4b47b240be7777f3059e947844c6e3d88839b211a6363c05992d359b9eb63dd95b3d19803e39c0886faf21ff02401384faa0369e1702f49b82ac497da5fc7afbb848bbba681b618d1d73fe60518b94fa010531ceb6de2e0a3d80c09eb4fc92ee4ffee719fe60790817230f458d8102405204e52efc21b4deb76cf90046907330714dbea17b8c95ed1d648ea5931f04fc9f35c2c6f811eeadabb67b211cefe86d6df76ed7b3011f2922faca7b306c0719
 密文:0f9495be68eb85750a333f656d085d049f05dfc6c264441cd3e52658bdc9767a047127f491a730b3c60d6ffd22568c38d25820b3aa3332a0e3cd0d0444851c651ab38ada9d8669092f1f3c016f895554fac3a8873e38cd856087f62ddae12aa1429cfaa7e6f088d4ebd28a1a635e53295729822446213ae53ec50dd38ba608fa
 原文:GeneralAndroid->Android將軍
 
 *
 *
 */

複製程式碼

DSA(Digital Signature Algorithm):資料簽名演算法,這是一種更高階的驗證方式,用作數字簽名。不單單隻有公鑰、私鑰,還有數字簽名。私鑰加密生成數字簽名,公鑰驗證資料及簽名。如果資料和簽名不匹配則認為驗證失敗。數字簽名的作用就是校驗資料在傳輸過程中不被修改。 使用姿勢如下所示:

package com.general.encryanddecode;
 
import javax.crypto.Cipher;
import java.security.*;
 
/**
 * 數字簽名用
 */
public class DSATest {
    private Key publicKey;
    private Key privateKey;
    private String oContent;
    private byte[] pContent;
    private byte[] sign;
 
    public DSATest(String oContent) {
        this.oContent = oContent;
        try{
            generateKeyPair();
        }catch (Exception e){
            e.printStackTrace();
        }
 
    }
 
    public void generateKeyPair() throws Exception {
 
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
        KeyPair kp = kpg.generateKeyPair();
        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();
        System.out.println("公鑰:" + BytesToHex.fromBytesToHex(publicKey.getEncoded()));
        System.out.println("私鑰:" + BytesToHex.fromBytesToHex(privateKey.getEncoded()));
 
    }
 
    public void sign() {
        try {
 
 
            Signature signature=Signature.getInstance("DSA");
            signature.initSign((PrivateKey) privateKey);
            signature.update(oContent.getBytes());
            sign=signature.sign();
            System.out.println("簽名:"+BytesToHex.fromBytesToHex(sign));
 
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void verify(){
        try {
 
 
            Signature signature=Signature.getInstance("DSA");
            signature.initVerify((PublicKey) publicKey);
            signature.update(oContent.getBytes());
            System.out.println("驗證:"+signature.verify(sign));;
 
 
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
    public static void main(String[] args){
        DSATest test=new DSATest("GeneralAndroid->Android將軍");
        test.sign();
        test.verify();
 
    }
 
}
/**
 *
 *
 公鑰:308201b83082012c06072a8648ce3804013082011f02818100fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c70215009760508f15230bccb292b982a2eb840bf0581cf502818100f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a0381850002818100e234691f5ec3b379d6b4e516be16ad21017ca3cef07ffbc485bc282a56164bb63b03ebc8c676c6092caf72e6eaccff2ab9fe6e30b3b459fa235008d689a8c8ba7dc50a3066c172cecb930776de0a04773fd62ca4cf9dccd68d1a4c4418bd1198488fad73a52a5fcdbff2d8b58d8344d8566027ccd9ac2b593a701a26dc268e25
 私鑰:3082014b0201003082012c06072a8648ce3804013082011f02818100fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c70215009760508f15230bccb292b982a2eb840bf0581cf502818100f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a041602146f1508747ab539097047199bdc1f53a42c1e5522
 簽名:302c021437788675af8edbdf83976313a94ef4bb99a9657502147eb1581542a970b1e9d954d9f593bea46ba48754
 驗證:true
 
 *
 *
 *
 *
 * */

複製程式碼

本篇博文就先講這麼多,加密與解密是一個複雜的方向,本文僅僅是入門前的使用,如果真要知其原理,還需要進一步研究密碼學相關的內容。

要說的內容就這麼多,如果文中有不對的地方,麻煩指出,如果喜歡我的文章,可以動動手指關注一下,贊一下,我會有更大的動力寫出更多的文章,轉載請註明出處:http://blog.csdn.net/android_jiangjun/article/details/78727139

相關文章