加密算法

概述

之前一直對加密相關(guān)的算法知之甚少赶袄,只知道類似DES揽涮、RSA等加密算法能對數(shù)據(jù)傳輸進(jìn)行加密,且各種加密算法各有優(yōu)缺點(diǎn)饿肺。但是一直沒有詳細(xì)的研究并形成系統(tǒng)的認(rèn)知蒋困。剛好最近看到一篇關(guān)于Android開發(fā)加密相關(guān)的文章,因此決定把加密相關(guān)的東西簡單梳理一下敬辣。

定義

數(shù)據(jù)加密的基本過程就是對原來為明文的文件或數(shù)據(jù)按某種算法進(jìn)行處理雪标,使其成為不可讀的一段代碼零院,通常稱為“密文”,使其只能在輸入相應(yīng)的密鑰之后才能顯示出本來內(nèi)容村刨,通過這樣的途徑來達(dá)到保護(hù)數(shù)據(jù)不被非法人竊取告抄、閱讀的目的。 該過程的逆過程為解密烹困,即將該編碼信息轉(zhuǎn)化為其原來數(shù)據(jù)的過程玄妈。

該段文字摘自百度百科

分類

  • 單向加密算法
    單向加密又稱為不可逆加密算法,在加密過程中不使用密鑰髓梅,明文由系統(tǒng)加密處理成密文拟蜻,密文無法解密。一般適合于驗(yàn)證枯饿,在驗(yàn)證過程中酝锅,重新輸入明文,并經(jīng)過同樣的加密算法處理奢方,得到相同的密文并被系統(tǒng)重新認(rèn)證搔扁。廣泛使用于口令加密。例如蟋字,用戶在注冊后密碼被經(jīng)過MD5加密后保存在數(shù)據(jù)庫稿蹲,這樣即使是數(shù)據(jù)庫管理員也沒法知道密碼是什么。
    該算法有如下特點(diǎn):
    1鹊奖、 對同一消息反復(fù)執(zhí)行加密得到相同的密文苛聘。
    2、加密算法生成的密文不可預(yù)見忠聚,和明文沒任何關(guān)系设哗。
    3、 明文的任何微小的變化都會對密文產(chǎn)生很大影響两蟀。
    4网梢、不可逆,即不能通過密文獲取明文赂毯。
    比較流行的加密算法:MD5和SHA1战虏。MD5與SHA1都是Hash算法,兩個相比欢瞪。MD5輸出是128位的活烙,SHA1輸出是160位的,MD5比SHA1快遣鼓,SHA1比MD5強(qiáng)度高啸盏。下面會有兩種算法的java代碼實(shí)現(xiàn)。

  • 對稱式加密算法
    對稱加密算法的特點(diǎn)是:使用的密鑰只有一個骑祟,發(fā)收信雙方都使用這個密鑰對數(shù)據(jù)進(jìn)行加密和解密回懦,要求解密方事先必須知道加密密鑰气笙。它的優(yōu)點(diǎn)是:算法公開、計(jì)算量小怯晕、加密速度快潜圃、加密效率高。缺點(diǎn)是:雙方都使用同樣鑰匙舟茶,安全性得不到保證谭期。每對用戶每次使用對稱加密算法時,都需要使用其他人不知道的惟一鑰匙吧凉,這會使得發(fā)收信雙方所擁有的鑰匙數(shù)量呈幾何級數(shù)增長隧出,密鑰管理成為用戶的負(fù)擔(dān)。對稱加密算法在分布式網(wǎng)絡(luò)系統(tǒng)上使用較為困難阀捅,主要是因?yàn)槊荑€管理困難胀瞪,使用成本較高。
    常見的對稱加密算法有:DES饲鄙、3DES凄诞、AES等。

  • 非對稱式加密算法
    非對稱加密算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰(privatekey)忍级。公開密鑰與私有密鑰是一對帆谍,如果用公開密鑰對數(shù)據(jù)進(jìn)行加密,只有用對應(yīng)的私有密鑰才能解密轴咱;如果用私有密鑰對數(shù)據(jù)進(jìn)行加密既忆,那么只有用對應(yīng)的公開密鑰才能解密。簡單的說是“公鑰加密嗦玖,私鑰解密;私鑰加密跃脊,公鑰解密”宇挫。
    常見的非對稱加密算法有:RSA。值得一提的是酪术,RSA是目前最有影響力的公鑰加密算法器瘪,它能夠抵抗到目前為止已知的絕大多數(shù)密碼攻擊,已被ISO推薦為公鑰數(shù)據(jù)加密標(biāo)準(zhǔn)绘雁。

常見的加密算法

  • MD5
    MD5橡疼,全稱是Message-Digest Algorithm 5(信息-摘要算法5)饺鹃,它是一種單向加密算法魔策,也就是只能加密,不能解密潭袱。MD5的作用是讓大容量信息在用數(shù)字簽名軟件簽署私人密鑰前被"壓縮成一種保密的格式挪略。作用基本與SHA1類似历帚。
    MD5目前的應(yīng)用一般有三種:
    1.一致性驗(yàn)證滔岳。
    MD5的典型應(yīng)用是對一段信息(Message)產(chǎn)生信息摘要(Message-Digest),以防止被篡改挽牢。我們常常在某些軟件下載站點(diǎn)的某軟件信息中看到其MD5值谱煤,它的作用就在于我們可以在下載該軟件后,對下載回來的文件用專門的軟件(如Windows MD5 Check等)做一次MD5校驗(yàn)禽拔,以確保我們獲得的文件與該站點(diǎn)提供的文件為同一文件刘离。
    2.數(shù)字簽名。
    MD5的典型應(yīng)用是對一段Message(字節(jié)串)產(chǎn)生fingerprint(指紋)睹栖,以防止被“篡改”硫惕。舉個例子,你將一段話寫在一個叫 readme.txt文件中磨淌,并對這個readme.txt產(chǎn)生一個MD5的值并記錄在案疲憋,然后你可以傳播這個文件給別人,別人如果修改了文件中的任何內(nèi)容梁只,你對這個文件重新計(jì)算MD5時就會發(fā)現(xiàn)(兩個MD5值不相同)缚柳。如果再有一個第三方的認(rèn)證機(jī)構(gòu),用MD5還可以防止文件作者的“抵賴”搪锣,這就是所謂的數(shù)字簽名應(yīng)用秋忙。
    3.安全訪問認(rèn)證
    MD5還廣泛用于操作系統(tǒng)的登陸認(rèn)證上,如在Unix系統(tǒng)中用戶的密碼是以MD5(或其它類似的算法)經(jīng)Hash運(yùn)算后存儲在文件系統(tǒng)中构舟。當(dāng)用戶登錄的時候灰追,系統(tǒng)把用戶輸入的密碼進(jìn)行MD5 Hash運(yùn)算,然后再去和保存在文件系統(tǒng)中的MD5值進(jìn)行比較狗超,進(jìn)而確定輸入的密碼是否正確弹澎。通過這樣的步驟,系統(tǒng)在并不知道用戶密碼的明碼的情況下就可以確定用戶登錄系統(tǒng)的合法性努咐。這可以避免用戶的密碼被具有系統(tǒng)管理員權(quán)限的用戶知道苦蒿。MD5將任意長度的“字節(jié)串”映射為一個128bit的大整數(shù),并且是通過該128bit反推原始字符串是困難的渗稍,換句話說就是佩迟,即使你看到源程序和算法描述,也無法將一個MD5的值變換回原始的字符串竿屹。
    MD5的加密算法代碼如下:
public static String MD5Encrypt(String msg){
        if (msg==null||msg.trim().length()==0){
            return "";
        }
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(msg.getBytes());
            byte[] encrypMsg = md.digest();
            return new String(encrypMsg);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

SHA的加密算法代碼如下:

//安全散列算法(Secure Hash Algorithm)报强,對長度不超過264位的二進(jìn)制消息產(chǎn)生160位的消息摘要輸出。
public static String SHAEncrypt(String msg){
        if (msg==null||msg.trim().length()==0){
            return "";
        }
        try {
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(msg.getBytes());
            byte[] encrypMsg = md.digest();
            return new String(encrypMsg);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
  • Base64
    Base64是網(wǎng)絡(luò)上最常見的用于傳輸8Bit字節(jié)代碼的編碼方式之一拱燃,Base64并不是安全領(lǐng)域的加密算法秉溉,其實(shí)Base64只能算是一個編碼算法,對數(shù)據(jù)內(nèi)容進(jìn)行編碼來適合傳輸。標(biāo)準(zhǔn)Base64編碼解碼無需額外信息即完全可逆坚嗜,即使你自己自定義字符集設(shè)計(jì)一種類Base64的編碼方式用于數(shù)據(jù)加密夯膀,在多數(shù)場景下也較容易破解。Base64編碼本質(zhì)上是一種將二進(jìn)制數(shù)據(jù)轉(zhuǎn)成文本數(shù)據(jù)的方案苍蔬。對于非二進(jìn)制數(shù)據(jù)诱建,是先將其轉(zhuǎn)換成二進(jìn)制形式,然后每連續(xù)6比特(2的6次方=64)計(jì)算其十進(jìn)制值碟绑,根據(jù)該值在A--Z,a--z,0--9,+,/ 這64個字符中找到對應(yīng)的字符俺猿,最終得到一個文本字符串「裰伲基本規(guī)則如下幾點(diǎn):
    1押袍、標(biāo)準(zhǔn)Base64只有64個字符(英文大小寫、數(shù)字和+凯肋、/)以及用作后綴等號谊惭;
    2、Base64是把3個字節(jié)變成4個可打印字符侮东,所以Base64編碼后的字符串一定能被4整除(不算用作后綴的等號)圈盔;
    3、等號一定用作后綴悄雅,且數(shù)目一定是0個驱敲、1個或2個。這是因?yàn)槿绻拈L度不能被3整除宽闲,Base64要在后面添加\0湊齊3n位众眨。為了正確還原,添加了幾個\0就加上幾個等號容诬。顯然添加等號的數(shù)目只能是0娩梨、1或2;
    嚴(yán)格來說Base64不能算是一種加密览徒,只能說是編碼轉(zhuǎn)換姚建。
Base64編碼表.png

作用:在計(jì)算機(jī)中任何數(shù)據(jù)都是按ascii碼存儲的,而ascii碼的128~255之間的值是不可見字符吱殉。而在網(wǎng)絡(luò)上交換數(shù)據(jù)時,比如說從A地傳到B地厘托,往往要經(jīng)過多個路由設(shè)備友雳,由于不同的設(shè)備對字符的處理方式有一些不同,這樣那些不可見字符就有可能被處理錯誤铅匹,這是不利于傳輸?shù)难荷蕖K跃拖劝褦?shù)據(jù)先做一個Base64編碼,統(tǒng)統(tǒng)變成可見字符,這樣出錯的可能性就大降低了流礁。

  • DES
    DES算法全稱為Data Encryption Standard涕俗,即數(shù)據(jù)加密標(biāo)準(zhǔn)算法,它是IBM公司于1975年研究成功并公開發(fā)表的神帅。DES算法的入口參數(shù)有三個:Key再姑、Data、Mode找御。其中 Key為7個字節(jié)共56位,是DES算法的工作密鑰;Data為8個字節(jié)64位元镀,是要被加密或被解密的數(shù)據(jù);Mode為DES的工作方式,有兩種:加密 或解密。
    DES算法的標(biāo)準(zhǔn)加密解密代碼如下:
private static final String PASSWORD_CRYPT_KEY = "!@#$%^&*()_+~`=-";

    private final static String DES = "DES";
    /**
     * 加密
     *
     * @param src 數(shù)據(jù)源
     * @param key 密鑰霎桅,長度必須是8的倍數(shù)
     * @return 返回加密后的數(shù)據(jù)
     */
public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
        //步驟一:根據(jù)key生成密鑰
        //DES算法要求有一個可信任的隨機(jī)數(shù)源
        SecureRandom sr = new SecureRandom();
        // 從原始密匙數(shù)據(jù)創(chuàng)建DESKeySpec對象
        DESKeySpec dks = new DESKeySpec(key);
        // 創(chuàng)建一個密匙工廠栖疑,然后用它把DESKeySpec轉(zhuǎn)換成
        // 一個SecretKey對象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);

        //步驟二:加密操作
        // Cipher對象實(shí)際完成加密操作
        Cipher cipher = Cipher.getInstance(DES);
        // 用密匙初始化Cipher對象
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
        // 現(xiàn)在,獲取數(shù)據(jù)并加密
        // 正式執(zhí)行加密操作
        return cipher.doFinal(src);
}
    /**
     * 解密
     *
     * @param src 數(shù)據(jù)源
     * @param key 密鑰滔驶,長度必須是8的倍數(shù)
     * @return 返回解密后的原始數(shù)據(jù)
     */
    public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
        // DES算法要求有一個可信任的隨機(jī)數(shù)源
        SecureRandom sr = new SecureRandom();
        // 從原始密匙數(shù)據(jù)創(chuàng)建一個DESKeySpec對象
        DESKeySpec dks = new DESKeySpec(key);
        // 創(chuàng)建一個密匙工廠遇革,然后用它把DESKeySpec對象轉(zhuǎn)換成
        // 一個SecretKey對象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher對象實(shí)際完成解密操作
        Cipher cipher = Cipher.getInstance(DES);
        // 用密匙初始化Cipher對象
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
        // 現(xiàn)在,獲取數(shù)據(jù)并解密
        // 正式執(zhí)行解密操作
        return cipher.doFinal(src);
    }
  • 3DES
    3DES也稱為3DESede或TripleDES揭糕,是三重?cái)?shù)據(jù)加密算法(TDEA萝快,Triple Data Encryption Algorithm)塊密碼的通稱。它相當(dāng)于是對每個數(shù)據(jù)塊應(yīng)用三次DES加密算法插佛。由于計(jì)算機(jī)運(yùn)算能力的增強(qiáng)杠巡,原版DES密碼的密鑰長度變得容易被暴力破解;3DES即是設(shè)計(jì)用來提供一種相對簡單的方法雇寇,即通過增加DES的密鑰長度來避免類似的攻擊氢拥。可以簡單理解為DES加密的升級版锨侯。
    3DES加密的過程為:C=Ek3(Dk2(Ek1(M)))嫩海。即明文M通過密鑰K1進(jìn)行DES加密,得到密文1囚痴。然后對得到的密文1通過密鑰K2進(jìn)行解密得到密文2叁怪。最后對得到的密文2通過密鑰3進(jìn)行加密得到最終的密文3。
    3DES解密過程為:M=Dk1(EK2(Dk3(C)))深滚。解密的過程基本是加密的反向操作奕谭,依次通過密鑰K3、K2痴荐、K1進(jìn)行解密血柳、加密以及解密的操作得到明文內(nèi)容。
    3DES算法的標(biāo)準(zhǔn)加密解密代碼如下:
public class TripleDESUtils {

    // 密鑰, 3DES的密鑰必須是24位的byte數(shù)組,否則會報(bào)錯
    private final static String secretKey = "123456789012345678901234";
    // 向量
    private final static String iv = "01234567";
    // 加解密統(tǒng)一使用的編碼方式
    private final static String encoding = "utf-8";

    /**
     * 3DES加密
     *
     * @param plainText 普通文本
     * @return
     * @throws Exception
     */
    public static String encode(String plainText) throws Exception {
        Key deskey = null;
        System.out.println("secretkey.length="+secretKey.length());
        System.out.println("iv.length="+iv.length());
        DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);

        Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
        byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
        return new String(Base64.encode(encryptData,Base64.DEFAULT),encoding);//從byte數(shù)組轉(zhuǎn)成字符串生兆,一般有兩種方式难捌,base64處理和十六進(jìn)制處理。
    }

    /**
     * 3DES解密
     *
     * @param encryptText 加密文本
     * @return
     * @throws Exception
     */
    public static String decode(String encryptText) throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, deskey, ips);

        byte[] decryptData = cipher.doFinal(Base64.decode(encryptText,Base64.DEFAULT));

        return new String(decryptData, encoding);
    }
}
  • AES
    高級加密標(biāo)準(zhǔn)(英語:Advanced Encryption Standard,縮寫:AES)根吁,在密碼學(xué)中又稱Rijndael加密法员淫,是美國聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。它屬于對稱加密算法击敌。它的出現(xiàn)是為了替代DES加密算法介返。
    AES算法的標(biāo)準(zhǔn)加密解密代碼如下:
/**偏移量,必須是16位字符串*/
    private static final String IV_STRING = "16-Bytes--String";

    /**
     * 默認(rèn)的密鑰
     */
    public static final String DEFAULT_KEY = "1bd83b249a414036";

    /**
     * 產(chǎn)生隨機(jī)密鑰(這里產(chǎn)生密鑰必須是16位)
     */
    public static String generateKey() {
        String key = UUID.randomUUID().toString();
        key = key.replace("-", "").substring(0, 16);// 替換掉-號
        return key;
    }

    public static String encryptData(String key, String content) {
        byte[] encryptedBytes = new byte[0];
        try {
            byte[] byteContent = content.getBytes("UTF-8");
            // 注意,為了能與 iOS 統(tǒng)一
            // 這里的 key 不可以使用 KeyGenerator愚争、SecureRandom映皆、SecretKey 生成
            byte[] enCodeFormat = key.getBytes();
            SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
            byte[] initParam = IV_STRING.getBytes();
            IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
            // 指定加密的算法、工作模式和填充方式
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            encryptedBytes = cipher.doFinal(byteContent);
            // 同樣對加密后數(shù)據(jù)進(jìn)行 base64 編碼
            return Base64Utils.encode(encryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String decryptData(String key, String content) {
        try {
            // base64 解碼
            byte[] encryptedBytes = Base64Utils.decode(content);
            byte[] enCodeFormat = key.getBytes();
            SecretKeySpec secretKey = new SecretKeySpec(enCodeFormat, "AES");
            byte[] initParam = IV_STRING.getBytes();
            IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
            byte[] result = cipher.doFinal(encryptedBytes);
            return new String(result, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static void main(String[] args) {
        String plainText = AESUtils.decryptData("F431E6FF9051DA07", "q8jHYk6LSbwC2K4zmr/wRZo8mlH0VdMzPEcAzQadTCpSrPQ/ZnTmuIvQxiLOnUXu");
        System.out.println("aes加密后: " + plainText);
    }
  • RSA
    RSA加密算法的名稱由三位發(fā)明人的名字首字母組合而成轰枝,它屬于非對稱加密算法捅彻。因此基本的加密方式也是通過兩個密鑰,實(shí)現(xiàn)過程是:公鑰加密鞍陨,私鑰解密步淹;私鑰加密,公鑰解密诚撵。RSA是目前最有影響力的公鑰加密算法缭裆,它能夠抵抗到目前為止已知的絕大多數(shù)密碼攻擊,已被ISO推薦為公鑰數(shù)據(jù)加密標(biāo)準(zhǔn)寿烟。
    RSA算法的標(biāo)準(zhǔn)加密解密代碼如下:
public static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcA";
public static final String PUBLIC_KEY =  "IGfMA0GCSqGSIb3DQEBAQUAA4GNA";
/** RSA最大加密明文大小 */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /** RSA最大解密密文大小 */
    private static final int MAX_DECRYPT_BLOCK = 128;

    /** 加密算法RSA */
    private static final String KEY_ALGORITHM = "RSA";

    /**
     * 生成公鑰和私鑰
     *
     * @throws Exception
     *
     */
    public static void getKeys() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(1024);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        String publicKeyStr = getPublicKeyStr(publicKey);
        String privateKeyStr = getPrivateKeyStr(privateKey);

        System.out.println("公鑰\r\n" + publicKeyStr);
        System.out.println("私鑰\r\n" + privateKeyStr);
    }

    public static String getPrivateKeyStr(PrivateKey privateKey)
            throws Exception {
        return new String(Base64.encode(privateKey.getEncoded(),Base64.DEFAULT));
    }

    public static String getPublicKeyStr(PublicKey publicKey) throws Exception {
        return new String(Base64.encode(publicKey.getEncoded(),Base64.DEFAULT));
    }

    /**
     * 公鑰加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKey(String data) throws Exception {
        byte[] dataByte = data.getBytes();
        byte[] keyBytes = Base64.decode(PUBLIC_KEY,Base64.DEFAULT);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        // 對數(shù)據(jù)加密
        // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = dataByte.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 對數(shù)據(jù)分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(dataByte, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(dataByte, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return new String(Base64.encode(encryptedData,Base64.DEFAULT));
    }

    /**
     * 私鑰解密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKey(String data) throws Exception {
        byte[] encryptedData = Base64.decode(data,Base64.DEFAULT);
        byte[] keyBytes = Base64.decode(PRIVATE_KEY,Base64.DEFAULT);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 對數(shù)據(jù)分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher
                        .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher
                        .doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return new String(decryptedData);
    }

常見的幾種加密算法已經(jīng)基本都有提到了澈驼,但是目前還只是對它們的概念和標(biāo)準(zhǔn)加密算法進(jìn)行了總結(jié),而且在實(shí)際項(xiàng)目中筛武,目前也只用了DES和3DES加密缝其,所以還需要對各種加密算法的使用場景進(jìn)行理解。希望上面的介紹也可以幫到大家徘六。

參考鏈接:
http://www.cnblogs.com/whoislcj/p/5887859.html
https://mp.weixin.qq.com/s/-Jb-_PpbEN5HYpueUqtxzA

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末内边,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子待锈,更是在濱河造成了極大的恐慌漠其,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件竿音,死亡現(xiàn)場離奇詭異和屎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)春瞬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門柴信,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人快鱼,你說我怎么就攤上這事。” “怎么了抹竹?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵线罕,是天一觀的道長。 經(jīng)常有香客問我窃判,道長钞楼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任袄琳,我火速辦了婚禮询件,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘唆樊。我一直安慰自己宛琅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布逗旁。 她就那樣靜靜地躺著嘿辟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪片效。 梳的紋絲不亂的頭發(fā)上红伦,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機(jī)與錄音淀衣,去河邊找鬼昙读。 笑死,一個胖子當(dāng)著我的面吹牛膨桥,可吹牛的內(nèi)容都是我干的蛮浑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼国撵,長吁一口氣:“原來是場噩夢啊……” “哼陵吸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起介牙,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤壮虫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后环础,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囚似,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年线得,在試婚紗的時候發(fā)現(xiàn)自己被綠了饶唤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡贯钩,死狀恐怖募狂,靈堂內(nèi)的尸體忽然破棺而出办素,到底是詐尸還是另有隱情,我是刑警寧澤祸穷,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布性穿,位于F島的核電站,受9級特大地震影響雷滚,放射性物質(zhì)發(fā)生泄漏需曾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一祈远、第九天 我趴在偏房一處隱蔽的房頂上張望呆万。 院中可真熱鬧,春花似錦车份、人聲如沸谋减。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逃顶。三九已至,卻和暖如春充甚,著一層夾襖步出監(jiān)牢的瞬間以政,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工伴找, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盈蛮,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓技矮,卻偏偏與公主長得像抖誉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子衰倦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 在開發(fā)應(yīng)用過程中袒炉,客戶端與服務(wù)端經(jīng)常需要進(jìn)行數(shù)據(jù)傳輸,涉及到重要隱私安全信息時樊零,開發(fā)者自然會想到對其進(jìn)行加密我磁,即使...
    閑庭閱讀 3,260評論 0 11
  • 這篇文章主要講述在Mobile BI(移動商務(wù)智能)開發(fā)過程中,在網(wǎng)絡(luò)通信驻襟、數(shù)據(jù)存儲夺艰、登錄驗(yàn)證這幾個方面涉及的加密...
    雨_樹閱讀 2,335評論 0 6
  • 最近公司用到RSA數(shù)據(jù)加密傳輸,本人也只會使用沉衣,并不知其原理郁副,剛好今天在csdn看到一位大牛的博客寫得很到位,遂搬...
    爸比好酷閱讀 1,414評論 0 1
  • 今天是吳鎮(zhèn)宇的生日,這么多年來固以,他給我們貢獻(xiàn)了很多經(jīng)典的電影,也貢獻(xiàn)了很多爛片嘱巾。 曾經(jīng)小七以為吳鎮(zhèn)宇主演的《戰(zhàn)國》...
    影視小七說閱讀 1,185評論 0 1
  • 今晚聽了《從“為什么”開始》這本書憨琳,其實(shí)之前已經(jīng)聽過一遍這本書,但是作為我們的思維主題還是再聽了一遍旬昭。這本書講的一...
    八杯水12138閱讀 587評論 0 0