DES趋急、AES、RSA加密

加密算法

  1. 單向加密: MD5 SHA
  2. Base64加密
  3. 對稱加密: AES (Advanced Encription Standard) \ DES (Data Encryption Standard)
  4. 非對稱加密:RSA

MD5 消息摘要算法5

MD5 (Message-Digest Algorithm 5)消息摘要算法5 是一種單向的加密算法,是不可逆的一種加密方式饵撑。

1. MD5加密的特點

  • 壓縮性:任意長度的數(shù)據(jù),計算出來的MD5值都是固定的
  • 容易計算: 從原數(shù)據(jù)計算出MD5值是非常方便的
  • 抗修改性: 對原數(shù)據(jù)做任何改動 哪怕之修改1個字節(jié),MD5值都有很大區(qū)別
  • 強抗碰撞:已知原數(shù)據(jù)和其MD5值剑梳,想找到一個具有相同MD5值的數(shù)據(jù)(偽造數(shù)據(jù))是非常困難的。

2. 應(yīng)用場景:

  • 文件一致性較驗
  • 數(shù)組簽名
  • 安全訪問認證
MD5 加密使用實例
 /**
     * MessageDigest 類為應(yīng)用程序提供信息摘要算法的功能滑潘,如 MD5 或 SHA 算法,信息摘要是安全的單項哈西函數(shù)垢乙,它接收任意大小的數(shù)據(jù),并輸出固定長度的哈希值
     * @param str
     * @return
     */
    public static String MD5Encode(String str){
        MessageDigest algorithm ;

        String md5 = "";
        try {
            //實例化一個采用MD5算法的 信息摘要
            algorithm = MessageDigest.getInstance("MD5");
            algorithm.reset();// 重置摘要 以供使用
            algorithm.update(str.getBytes());//使用bytes更新摘要
            byte[] bytes = algorithm.digest();
            md5 = toHexString(bytes,"");
            Log.d(TAG,"MD5Encode:"+str+",md5:"+md5);
        }catch (Exception e){
            e.printStackTrace();
        }finally {

        }

        return md5;
    }

    public static String toHexString(byte[] bytes,String seperator){

        StringBuffer hexString = new StringBuffer();
        for(byte b:bytes){
            String hex = Integer.toHexString(b&0xff);
            if(hex.length() == 1){
                hexString.append("0");
            }
            hexString.append(hex).append(seperator);
        }
        return hexString.toString();
    }

SHA 安全散列算法 : 也是一種單向的數(shù)據(jù)加密算法

 /**
     * SHA 安全散列算法
     * @param str
     * @return
     */
    public static String SHAEncode(String str){

        MessageDigest algorithm;
        String sha = "";
        try {
            algorithm = MessageDigest.getInstance("SHA");
            algorithm.reset();
            algorithm.update(str.getBytes());
            byte[] bytes = algorithm.digest();
            sha = toHexString(bytes,"");
        }catch (NoSuchAlgorithmException e){

        }finally {

        }
        Log.d(TAG,"SHAEncode:"+str+",sha:"+sha);
        return sha;
    }

Base64 加密算法

Base64 并不是安全領(lǐng)域的加密算法,只能算是一個編碼算法语卤。標準的Base64編碼解碼無需任何額外的信息即完全可逆追逮。
Base64 編碼 本質(zhì)上是一種將二進制數(shù)據(jù)轉(zhuǎn)換成文本數(shù)據(jù)的方案。對于非二進制數(shù)據(jù)粹舵,是先將其轉(zhuǎn)換成二進制形式钮孵,然后每連續(xù)6個比特(2^6 = 64) 計算其十進制值,根據(jù)該值在A-Z眼滤、a-z巴席、0-9、+柠偶、/ 這64個字符種找到對應(yīng)的字符情妖,最終得到一個文本串。

  • 標準的Base64只有64個字符(A-Z诱担、a-z毡证、0-9、+蔫仙、/)以及用作后綴的等號
  • Base64是把3個子節(jié)變成4個字符,所以base64編碼后的字符串一定能狗被4整除(不算用作后綴的=)
  • 等號一定用作后綴料睛,并且數(shù)目一定是0個、1個和2個摇邦。這是因為如果原文長度不能被3整除恤煞,Base64要在后面添加\0湊齊3n位.為了正確還原,添加了幾個\0就加上幾個等號施籍。顯然添加等號的數(shù)目只能是0居扒、1或2;
  • 嚴格來說Base64不能算一種加密,只能說是編碼轉(zhuǎn)換丑慎。


    image
public static String base64Encode(String origStr){
        byte[] endcode =  Base64.encode(origStr.getBytes(),Base64.DEFAULT);
        String encodeStr = new String(endcode);
        Log.d(TAG,"origStr:"+origStr+",endcodeStr:"+encodeStr);
        return encodeStr;
    }

    public static String base64Decode(String encodedStr){

        byte[] orign = Base64.decode(encodedStr,Base64.DEFAULT);
        String orignStr = new String(orign);
        return orignStr;
    }
  • 針對Base64.DEFAULT參數(shù)說明

DEFAULT 這個參數(shù)是默認喜喂,使用默認的方法來加密

NO_PADDING 這個參數(shù)是略去加密字符串最后的”=”

NO_WRAP 這個參數(shù)意思是略去所有的換行符(設(shè)置后CRLF就沒用了)

CRLF 這個參數(shù)看起來比較眼熟瓤摧,它就是Win風(fēng)格的換行符,意思就是使用CR LF這一對作為一行的結(jié)尾而不是Unix風(fēng)格的LF

URL_SAFE 這個參數(shù)意思是加密時不使用對URL和文件名有特殊意義的字符來作為加密字符玉吁,具體就是以-和_取代+和/

DES加密(Data Encryption Standard) 數(shù)據(jù)加密標準

  • DES加密算法出自IBM的研究,后來被美國政府采用照弥,之后廣為流傳。但近年來使用越來越少进副,因為DES 使用56位密鑰这揣,以現(xiàn)代的計算能力,24小時即可破解影斑。
  • DES 使用固定的8個字節(jié)(8bytes)作為密鑰,初始化向量 也為8bytes

常用常量:

    private final static String HEX = "0123456789ABCDEF";
    private final static String TRANSFORMATION = "DES/CBC/PKCS5Padding";//DES是加密方式 CBC是工作模式 PKCS5Padding是填充模式
    private final static String IVPARAMETERSPEC = "01020304";////初始化向量參數(shù)给赞,AES 為16bytes. DES 為8bytes.
    private final static String ALGORITHM = "DES";//DES是加密方式
    private static final String SHA1PRNG = "SHA1PRNG";//// SHA1PRNG 強隨機種子算法, 要區(qū)別4.2以上版本的調(diào)用方法
// 初始化向量(8字節(jié)),隨意填充
    private static byte[] iv = { 'a', 'b', 'c', 'd', 'e', 1, 2, '*'};

    /**
     * DES (Data Encryption Standard)  數(shù)據(jù)標準加密:DES 加密的Key 只能是8byte (8個字節(jié))
     * @param key
     * @param encryptText
     * @return
     */
    public static String DESEncode(String key,String encryptText){
        byte[] keyBytes = key.getBytes();//原始的加密key

        //SecretKeySpec - 為加密后的秘鑰
        SecretKeySpec secrectKey = new SecretKeySpec(keyBytes,"DES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        Cipher cipher = null;
        String output = "";
        try {
            cipher= Cipher.getInstance("DES/CBC/PKCS5Padding");//加密算法/工作方式/?
            cipher.init(Cipher.ENCRYPT_MODE,secrectKey,ivParameterSpec);//指定加密動作 和加密鑰
            byte[] encryptData = cipher.doFinal(encryptText.getBytes());
            output = Base64.encodeToString(encryptData,Base64.DEFAULT);

        }catch (Exception e){
            e.printStackTrace();
        }finally {

        }
        return output;
    }

    public static String DESDecode(String key,String decryptString){

        byte[] orginKey = key.getBytes();
        SecretKeySpec secretKeySpec = new SecretKeySpec(orginKey,"DES");

        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        byte[] base64Decode = Base64.decode(decryptString.getBytes(),Base64.DEFAULT);
        Cipher cipher = null;
        String decodeStr = "";
        try {
            cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,ivParameterSpec);
            byte[] descrptData = cipher.doFinal(base64Decode);
            decodeStr = new String(descrptData);
        }catch (Exception e){
            e.printStackTrace();
        }finally {

        }
        return decodeStr;
    }
    
    
    測試代碼:
        String org = "大漠孤煙直";
      
        String desEncode = EncodeUtils.DESEncode("*()&^%$#",org);
        String desDecode = EncodeUtils.DESDecode("*()&^%$#",desEncode);
        Log.d(TAG,"orig:"+org+",desEncode:"+desEncode+",desDecode:"+desDecode);

DES的擴展 3DES

3DES是DES加密算法的一種模式鸥昏,它使用3條64位的密鑰對數(shù)據(jù)進行三次加密塞俱。
3DES(即Triple DES)是DES向AES過渡的加密算法(1999年,NIST將3-DES指定為過渡的加密標準)吏垮,是DES的一個更安全的變形障涯。

AES (Advanced Encryption Standard) 高級加密標準。AES 本身就是為了取代DES的,AES 具有更好的安全性膳汪、效率和靈活性唯蝶。

/**
     * 真正的加密過程
     * 1.通過密鑰得到一個密鑰專用的對象SecretKeySpec
     * 2.Cipher 加密算法,加密模式和填充方式三部分或指定加密算 (可以只用寫算法然后用默認的其他方式)Cipher.getInstance("AES");
     * @param key
     * @param str
     * @return
     */
    public static String AESEncode(String key,String str){
        String result = "";
        SecretKeySpec secretKeySpec = new SecretKeySpec(generateKey(key),"AES");
        try {
            Cipher cipher = Cipher.getInstance("AES");//生成Cipher
            cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,new IvParameterSpec(new byte[cipher.getBlockSize()]));
            byte[] encrypted = cipher.doFinal(str.getBytes());
            result = toHexString(encrypted,"");
        }catch (Exception e){

        }finally {

        }
        return result;
    }


    /**
     * 生成 128遗嗽、192粘我、256位 秘鑰
     * @param rawKey
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static byte[] generateKey(String rawKey){
        //秘鑰生成器
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
            sr.setSeed(rawKey.getBytes());
            keyGenerator.init(128,sr);
            SecretKey sKey = keyGenerator.generateKey();
            byte[] mKey = sKey.getEncoded();
            return mKey;
        }catch (Exception e){
            e.printStackTrace();
        }finally {

        }
        return null;
    }


    public static String AESDecode(String key_seed,String encrypedStr){

        byte[] rawData = toByte(encrypedStr);
        String result = "";
        SecretKeySpec secretKeySpec = new SecretKeySpec(generateKey(key_seed),"AES");
        try {
            Cipher cipher = Cipher.getInstance("AES");//生成Cipher
            cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,new IvParameterSpec(new byte[cipher.getBlockSize()]));
            byte[] decrypted = cipher.doFinal(rawData);
            result = new String(decrypted);
        }catch (Exception e){
            e.printStackTrace();
        }finally {

        }
        return result;


    }

    // 將十六進制字符串為十進制字符串
    private static String fromHex(String hex) {
        return new String(toByte(hex));
    }

    // 將十六進制字符串為十進制字節(jié)數(shù)組
    private static byte[] toByte(String hex) {
        int len = hex.length() / 2;
        byte[] result = new byte[len];
        for (int i = 0; i < len; i++) {
            result[i] = Integer.valueOf(hex.substring(2 * i, 2 * i + 2), 16)
                    .byteValue();
        }
        return result;
    }

RSA 為非對稱加密

RSA算法是最流行的公鑰密碼算法,使用長度可以變化的密鑰痹换。
RSA算法原理如下:

1.隨機選擇兩個大質(zhì)數(shù)p和q征字,p不等于q,計算N=pq娇豫;
2.選擇一個大于1小于N的自然數(shù)e匙姜,e必須與(p-1)(q-1)互素。
3.用公式計算出d:d×e = 1 (mod (p-1)(q-1)) 冯痢。
4.銷毀p和q氮昧。

RSA的安全性依賴于大數(shù)分解,小于1024為的 N 被證明是不安全的浦楣,而且由于RSA算法進行的搜時大數(shù)計算袖肥,使得RSA最快的情況也比DES慢上倍,這是RSA最大的缺陷振劳。因此通常只能用于加密少量數(shù)據(jù)或者加密密鑰椎组,但RSA仍然不失為一種高強度的算法。

如何使用RSA呢历恐?

  • 第一步 生成秘鑰對寸癌。
  /**
     * 隨機生成RSA密鑰對
     *
     * @param keyLength 密鑰長度选调,范圍:512~2048
     *                  一般1024
     * @return
     */
    public static KeyPair generateRSAKeyPair(int keyLength) {
        try {
            KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
            kpg.initialize(keyLength);
            return kpg.genKeyPair();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
  • 第二步 使用公鑰加密 使用秘鑰解密 或者使用秘鑰加密、公鑰解密灵份。
    /**
     * 私鑰加密
     *
     * @param data       待加密數(shù)據(jù)
     * @param privateKey 密鑰
     * @return byte[] 加密數(shù)據(jù)
     */
    public static byte[] encryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception {
        // 得到私鑰
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);
        KeyFactory kf = KeyFactory.getInstance(RSA);
        PrivateKey keyPrivate = kf.generatePrivate(keySpec);
        // 數(shù)據(jù)加密
        Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, keyPrivate);
        return cipher.doFinal(data);
    }

/**
     * 公鑰解密
     *
     * @param data      待解密數(shù)據(jù)
     * @param publicKey 密鑰
     * @return byte[] 解密數(shù)據(jù)
     */
    public static byte[] decryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {
        // 得到公鑰
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
        KeyFactory kf = KeyFactory.getInstance(RSA);
        PublicKey keyPublic = kf.generatePublic(keySpec);
        // 數(shù)據(jù)解密
        Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING);
        cipher.init(Cipher.DECRYPT_MODE, keyPublic);
        return cipher.doFinal(data);
    }
/**
     * 私鑰加密
     *
     * @param data       待加密數(shù)據(jù)
     * @param privateKey 密鑰
     * @return byte[] 加密數(shù)據(jù)
     */
    public static byte[] encryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception {
        // 得到私鑰
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);
        KeyFactory kf = KeyFactory.getInstance(RSA);
        PrivateKey keyPrivate = kf.generatePrivate(keySpec);
        // 數(shù)據(jù)加密
        Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, keyPrivate);
        return cipher.doFinal(data);
    }
/**
     * 使用私鑰進行解密
     */
    public static byte[] decryptByPrivateKey(byte[] encrypted, byte[] privateKey) throws Exception {
        // 得到私鑰
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);
        KeyFactory kf = KeyFactory.getInstance(RSA);
        PrivateKey keyPrivate = kf.generatePrivate(keySpec);

        // 解密數(shù)據(jù)
        Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING);
        cp.init(Cipher.DECRYPT_MODE, keyPrivate);
        byte[] arr = cp.doFinal(encrypted);
        return arr;
    }

測試代碼:



        KeyPair keyPair = EncodeUtils.generateRSAKeyPair(DEFAULT_KEY_SIZE);
        RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();

        try {
            byte[]encrypteBytes = EncodeUtils.encryptByPublicKey(org.getBytes(),publicKey.getEncoded());
//            String encryptStr = EncodeUtils.base64Encode(encrypteBytes);
            byte[]base64Bytes  = Base64.encode(encrypteBytes,Base64.DEFAULT);

            String encodeStr = new String(base64Bytes);



            byte [] tmp = Base64.decode(encodeStr,Base64.DEFAULT);
            byte[]decryptBytes = EncodeUtils.decryptByPrivateKey(tmp,privateKey.getEncoded());
            String decodeStr = new String(decryptBytes);
            Log.d(TAG,"org:"+org+",encodeStr:"+encodeStr+",decodeStr:"+decodeStr);


        }catch (Exception e){
            e.printStackTrace();
        }

    }

參考鏈接:
http://www.cnblogs.com/whoislcj/p/5887859.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哮洽,隨后出現(xiàn)的幾起案子填渠,更是在濱河造成了極大的恐慌,老刑警劉巖鸟辅,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氛什,死亡現(xiàn)場離奇詭異,居然都是意外死亡匪凉,警方通過查閱死者的電腦和手機枪眉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來再层,“玉大人贸铜,你說我怎么就攤上這事∧羰埽” “怎么了蒿秦?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蛋济。 經(jīng)常有香客問我棍鳖,道長,這世上最難降的妖魔是什么碗旅? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任渡处,我火速辦了婚禮,結(jié)果婚禮上祟辟,老公的妹妹穿的比我還像新娘医瘫。我一直安慰自己,他們只是感情好川尖,可當(dāng)我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布登下。 她就那樣靜靜地躺著,像睡著了一般叮喳。 火紅的嫁衣襯著肌膚如雪被芳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天馍悟,我揣著相機與錄音畔濒,去河邊找鬼。 笑死锣咒,一個胖子當(dāng)著我的面吹牛侵状,可吹牛的內(nèi)容都是我干的赞弥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼趣兄,長吁一口氣:“原來是場噩夢啊……” “哼绽左!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起艇潭,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤拼窥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蹋凝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲁纠,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年鳍寂,在試婚紗的時候發(fā)現(xiàn)自己被綠了改含。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡迄汛,死狀恐怖捍壤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情隔心,我是刑警寧澤白群,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站硬霍,受9級特大地震影響帜慢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜唯卖,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一粱玲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拜轨,春花似錦抽减、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至法牲,卻和暖如春史汗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拒垃。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工停撞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓戈毒,卻偏偏與公主長得像艰猬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子埋市,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,665評論 2 354

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