Android常用加密方式

加密解密簡介

加密技術是最常用的安全保密手段,利用技術手段把重要的數據變爲亂碼(加密)傳送,到達目的地後再用相同或不同的手段還原(解密)。加密技術包括兩個元素:算法和密鑰。算法是將普通的信息或者可以理解的信息與一串數字(密鑰)結合,產生不可理解的密文的步驟,密鑰是用來對數據進行編碼和解密的一種算法。在安全保密中,可通過適當的鑰加密技術和管理機制來保證網絡的信息通信安全。

加迷解密分類

分爲不可逆和可逆,可逆又分爲對稱密鑰體制和非對稱密鑰體制兩種。

祕鑰加密技術的密碼體制分爲對稱密鑰體制和非對稱密鑰體制兩種。數據加密技術分爲兩類,即對稱加密(私人密鑰加密)和非對稱加密(公開祕鑰加密)。對稱加密以數據加密標準(DES,Data Encryption Standard)算法爲典型代表,非對稱加密通常以RSA(Rivest Shamir Ad1eman)算法爲代表。對稱加密的加密祕鑰和解密密鑰相同,而非對稱加密的加密密鑰和解密密鑰不同,加密密鑰可以公開而解密密鑰需要保密。

不可逆

單項的加密,不能解密。

MD5、SHA、HMAC這三種加密算法,可謂是非可逆加密,就是不可解密的加密方法。

我們通常只把他們作爲加密的基礎,單純的以上三種的加密並不可靠。
MD5、SHA 可以通過暴力碰撞算法破解。

對稱加密

對稱加密指的就是加密和解密使用同一個祕鑰,所以叫做對稱加密。對稱加密只有一個祕鑰,作爲私鑰。

對稱加密採用了對稱密碼編碼技術,它的特點是文件加密和解密使用相同的祕鑰,即加密密鑰也可以用作解密密鑰,這種方法在密碼學中叫做對稱加密算法,對稱加密算法使用起來簡單快捷,密鑰較短,且破譯困難,除了數據加密標準(DES),另一個對稱密鑰加密系統是國際數據加密算法(IDEA),它比DES的加密性好,而且對計算機功能要求也沒有那麼高。IDEA加密標準由PGP(Pretty Good Privacy)系統使用。

對稱性加密算法有:AES、DES、3DES

非對稱加密

非對稱加密指的是:加密和解密使用不同的祕鑰,一把作爲公開的公鑰,另一把作爲私鑰。公鑰加密的信息,只有私鑰才能解密。私鑰加密的信息,只有公鑰才能解密。

非對稱加密指的是:加密和解密使用不同的祕鑰,一把作爲公開的公鑰,另一把作爲私鑰。公鑰加密的信息,只有私鑰才能解密。私鑰加密的信息,只有公鑰才能解密。

1976年,美國學者Dime和Henman爲解決信息公開傳送和密鑰管理問題,提出一種新的密鑰交換協議,允許在不安全的媒體上的通訊雙方交換信息,安全地達成一致的密鑰,這就是“公開密鑰系統”。相對於“對稱加密算法”這種方法也叫做“非對稱加密算法”。與對稱加密算法不同,非對稱加密算法需要兩個密鑰:公開密鑰(publickey)和私有密 (privatekey)。公開密鑰與私有密鑰是一對,如果用公開密鑰對數據進行加密,只有用對應的私有密鑰才能解密;如果用私有密鑰對數據進行加密,那麼只有用對應的公開密鑰才能解密。因爲加密和解密使用的是兩個不同的密鑰,所以這種算法叫作非對稱加密算法。

非對稱性算法有:RSA、DSA、ECC

散列/哈希算法有:MD5、SHA1

其他常用算法:Base64

BASE64

Base64嚴格地說,屬於編碼格式,而非加密算法,用於二進制內容轉換爲可編輯的文本內容。

Base64也會經常用作一個簡單的“加密”來保護某些數據,而真正的加密通常都比較繁瑣。

編碼後的內容,是由64個字符(大小寫英文字母 0-9 + / (= 補位符,填充字符))組成的序列,成爲Base64。可逆的編碼方式。

常見於郵件、http加密,截取http信息,你就會發現登錄操作的用戶名、密碼字段通過BASE64加密的。

Android中自帶的Base64加密算法:

  String s = "xiaoyehai";

        //加密
        String encode = Base64.encodeToString(s.getBytes(), Base64.NO_WRAP);

        //解密
        byte[] decode = Base64.decode(encode.getBytes(), Base64.DEFAULT);
        Log.e("xyh", "encode: " + encode); //eGlhb3llaGFp
        Log.e("xyh", "decode: " +new String(decode,0,decode.length)); //xiaoyehai

在encode的時候,會有一個參數Flags(即上面代碼中的Base64.DEFAULT)這個參數有什麼用呢?根據Android SDK的描述,這種參數有5個:

DEFAULT 這個參數是默認,使用默認的方法來加密
CRLF 這個參數看起來比較眼熟,它就是Win風格的換行符,意思就是使用CRLF 這一對作爲一行的結尾而不是Unix風格的LF
NO_PADDING 這個參數是略去加密字符串最後的”=”
NO_WRAP 這個參數意思是略去所有的換行符(設置後CRLF就沒用了)
URL_SAFE 這個參數意思是加密時不使用對URL和文件名有特殊意義的字符來作爲加密字符,具體就是以-和 _ 取代+和/

MD5

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊算法之一(又譯摘要算法、哈希算法),主流編程語言普遍已有MD5實現。將數據(如漢字)運算爲另一固定長度值,是雜湊算法的基礎原理,MD5的前身有MD2、MD3和MD4。

MD5本質是一種散列函數,用以提供消息的完整性保護。

單項的加密,不能解密,長度固定(32位)。

通過對任意長度的信息逐位進行計算,產生一個二進制長度爲128位(十六進制長度就是32位)的 hash 值, 不同的文件產生相同的hash的可能性是非常小。

特點:

1.壓縮性:任意長度的數據,算出的MD5值長度都是固定的;

2.容易計算:從原數據計算出MD5值很容易;

3.抗修改性:對原數據進行任何改動,哪怕只修改1個字節,所得到的MD5值都有很大的區別;

4.強抗碰撞:已知原數據和其MD5值,想找到一個具有相同MD5值的數據(及僞造數據)是非常困難的;

5.不可逆:MD5理論上是不可逆的(但是現在已經可以暴力破解了)。

使用場景:

1.驗證密碼:只要算法不變,就能和服務器上的MD5匹配;

2.文件完整性的校驗:當下載一個文件時,服務器返回的信息包括這個文件的md5,在本地下載完畢時進行md5加密,將兩個md5值進行比較,如果一致則說明文件完整沒有丟包現象。

在這裏插入圖片描述

MD5加密工具類


/**
 * Created by : Administrator
 * Create date : 2019/5/16 22:34
 * description : md5加密工具類
 */
public class MD5Utils {

    public static String md5(String str) {
        if (str == null) {
            return "";
        } else {
            try {
                MessageDigest messageDigest = MessageDigest.getInstance("MD5");
                messageDigest.reset();
                messageDigest.update(str.getBytes("UTF-8"));
                byte[] byteArray = messageDigest.digest();
                StringBuffer md5StrBuff = new StringBuffer();
                for (int i = 0; i < byteArray.length; ++i) {
                    if (Integer.toHexString(255 & byteArray[i]).length() == 1) {
                        md5StrBuff.append("0").append(Integer.toHexString(255 & byteArray[i]));
                    } else {
                        md5StrBuff.append(Integer.toHexString(255 & byteArray[i]));
                    }
                }

                return md5StrBuff.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "";
    }


    public static String md5(byte[] target, int len) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(target, 0, len);
            byte[] byteArray = messageDigest.digest();
            StringBuffer md5StrBuff = new StringBuffer();
            for (int i = 0; i < byteArray.length; ++i) {
                if (Integer.toHexString(255 & byteArray[i]).length() == 1) {
                    md5StrBuff.append("0").append(Integer.toHexString(255 & byteArray[i]));
                } else {
                    md5StrBuff.append(Integer.toHexString(255 & byteArray[i]));
                }
            }

            return md5StrBuff.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 獲取文件的MD5
     *
     * @param file
     * @return
     */
    public static String getFileMD5(File file) {
        if (!file.isFile()) {
            return null;
        } else {
            MessageDigest digest = null;
            FileInputStream in = null;
            byte[] buffer = new byte[1024];

            try {
                digest = MessageDigest.getInstance("MD5");
                in = new FileInputStream(file);

                while (true) {
                    int len;
                    if ((len = in.read(buffer, 0, 1024)) == -1) {
                        in.close();
                        break;
                    }

                    digest.update(buffer, 0, len);
                }
            } catch (Exception var6) {
                var6.printStackTrace();
                return null;
            }

            BigInteger bigInt = new BigInteger(1, digest.digest());
            return bigInt.toString(16);
        }
    }

    /**
     * 獲取文件夾的MD5
     *
     * @param file
     * @param listChild
     * @return
     */
    public static Map<String, String> getDirMD5(File file, boolean listChild) {
        if (!file.isDirectory()) {
            return null;
        } else {
            Map<String, String> map = new HashMap();
            File[] files = file.listFiles();

            for (int i = 0; i < files.length; ++i) {
                File f = files[i];
                if (f.isDirectory() && listChild) {
                    map.putAll(getDirMD5(f, listChild));
                } else {
                    String md5 = getFileMD5(f);
                    if (md5 != null) {
                        map.put(f.getPath(), md5);
                    }
                }
            }
            return map;
        }
    }
}

SHA

安全散列算法,數字簽名工具 , 長度比MD5要長,所以更安全,但是加密的效率要比MD5慢一些.

安全散列算法SHA (Secure Hash Algorithm),用於確保信息傳輸完整一致。SHA基於MD5實現。

是美國國家標準技術研究所發佈的國家標準FIPS PUB 180,最新的標準已經於2008年更新到FIPS PUB 180-3。其中規定了SHA-1,SHA-224,SHA-256,SHA-384,和SHA-512這幾種單向散列算法。SHA-1,SHA-224和SHA-256適用於長度不超過264二進制位的消息。SHA-384和SHA-512適用於長度不超過2128二進制位的消息。

SHA1有如下特性:

不可以從消息摘要中復原信息;
兩個不同的消息不會產生同樣的消息摘要。

著名的圖片加載框架Glide在緩存key時就採用的此加密
文件的秒傳功能,以及相同的v4包衝突都是可以根據sha1值進行比對的

/**
*  使用sha-1方式進行加密
*  @return
        */
       public static String digest(String content){
        StringBuilder builder = new StringBuilder();
        try {
            MessageDigest msgDitest = MessageDigest.getInstance("SHA-1");
            msgDitest.update(content.getBytes());
            byte[] digests = msgDitest.digest();
            //將每個字節轉爲16進制
            for (int i=0;i<digests.length;i++){
                builder.append(Integer.toHexString(digests[i] & 0xff +8));//+8爲加鹽操作
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return  builder.toString();
       }

AES加密

AES加密是一種高級加密標準,是一種區塊加密標準。它是一個對稱密碼,就是說加密和解密用相同的密鑰。WPA/WPA2經常用的加密方式就是AES加密算法。

高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。 這個標準用來替代原先的DES,已經被多方分析且廣爲全世界所使用,Android 中的AES 加密 祕鑰 key 必須爲16/24/32位字節,否則拋異常。

在這裏插入圖片描述

package com.xiaoyehai.sdwydc.utils;

import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import com.xiaoyehai.sdwydc.constant.AppConstant;

import java.security.Provider;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * AES加密解密
 * Created by xiaoyehai on 2018/12/28 0028.
 */

public class AESUtils {

    private final static String HEX = "0123456789ABCDEF";
    private static final String CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";//AES是加密方式 CBC是工作模式 PKCS5Padding是填充模式
    private static final String AES = "AES";//AES 加密
    private static final String SHA1PRNG = "SHA1PRNG";// SHA1PRNG 強隨機種子算法, 要區別4.2以上版本的調用方法

    /**
     * 生成隨機數,可以當做動態的密鑰 加密和解密的密鑰必須一致,不然將不能解密
     */
    public static String generateKey() {
        try {
            SecureRandom localSecureRandom = SecureRandom.getInstance(SHA1PRNG);
            byte[] bytes_key = new byte[20];
            localSecureRandom.nextBytes(bytes_key);
            String str_key = toHex(bytes_key);
            return str_key;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 對密鑰進行處理
     *
     * @param seed
     * @return
     * @throws Exception
     */
    private static byte[] getRawKey(byte[] seed) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance(AES);
        //for android
        SecureRandom sr = null;
        // 在4.2以上版本中,SecureRandom獲取方式發生了改變
        int sdk_version = android.os.Build.VERSION.SDK_INT;
        if (sdk_version > 23) {  // Android  6.0 以上
            sr = SecureRandom.getInstance(SHA1PRNG, new CryptoProvider());
        } else if (android.os.Build.VERSION.SDK_INT >= 17) {   //4.2及以上
            sr = SecureRandom.getInstance(SHA1PRNG, "Crypto");
        } else {
            sr = SecureRandom.getInstance(SHA1PRNG);
        }


        // for Java
        // secureRandom = SecureRandom.getInstance(SHA1PRNG);
        sr.setSeed(seed);
        kgen.init(128, sr); //256 bits or 128 bits,192bits
        //AES中128位密鑰版本有10個加密循環,192比特密鑰版本有12個加密循環,256比特密鑰版本則有14個加密循環。
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return raw;
    }

    /**
     * 加密
     */
    public static String encrypt(String key, String cleartext) {
        if (TextUtils.isEmpty(cleartext)) {
            return cleartext;
        }
        try {
            byte[] result = encrypt(key, cleartext.getBytes());
            //            return Base64Encoder.encode(result);
            return new String(Base64.encode(result, Base64.DEFAULT));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 加密
     */
    private static byte[] encrypt(String key, byte[] clear) throws Exception {
        byte[] raw = getRawKey(key.getBytes());
        SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
        Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        byte[] encrypted = cipher.doFinal(clear);
        return encrypted;
    }

    /**
     * 解密
     */
    public static String decrypt(String key, String encrypted) {
        if (TextUtils.isEmpty(encrypted)) {
            return encrypted;
        }
        try {
            //            byte[] enc = Base64Decoder.decodeToBytes(encrypted);
            byte[] enc = Base64.decode(encrypted, Base64.DEFAULT);
            byte[] result = decrypt(key, enc);
            return new String(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密
     */
    private static byte[] decrypt(String key, byte[] encrypted) throws Exception {
        byte[] raw = getRawKey(key.getBytes());
        SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
        Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

    //二進制轉字符
    public static String toHex(byte[] buf) {
        if (buf == null)
            return "";
        StringBuffer result = new StringBuffer(2 * buf.length);
        for (int i = 0; i < buf.length; i++) {
            appendHex(result, buf[i]);
        }
        return result.toString();
    }

    private static void appendHex(StringBuffer sb, byte b) {
        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
    }


    // 增加  CryptoProvider  類

    public static class CryptoProvider extends Provider {
        /**
         * Creates a Provider and puts parameters
         */
        public CryptoProvider() {
            super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
            put("SecureRandom.SHA1PRNG",
                    "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
            put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
        }
    }
}

DES加密

DES(Data Encryption Standard,數據加密算法)
是IBM公司於1975年研究成功並公開發表的,是一種堆成加密算法.
在這裏插入圖片描述

 	private final static String HEX = "0123456789ABCDEF";
    private final static String TRANSFORMATION = "DES/CBC/PKCS5Padding";//DES是加密方式 CBC是工作模式 PKCS5Padding是填充模式
    private final static String IVPARAMETERSPEC = "01020304";////初始化向量參數,AES 爲16bytes. DES 爲8bytes.
    private final static String ALGORITHM = "DES";//DES是加密方式
    private static final String SHA1PRNG = "SHA1PRNG";//// SHA1PRNG 強隨機種子算法, 要區別4.2以上版本的調用方法

/*
 * 生成隨機數,可以當做動態的密鑰 加密和解密的密鑰必須一致,不然將不能解密
 */
    public static String generateKey() {
        try {
            SecureRandom localSecureRandom = SecureRandom.getInstance(SHA1PRNG);
            byte[] bytes_key = new byte[20];
            localSecureRandom.nextBytes(bytes_key);
            String str_key = toHex(bytes_key);
            return str_key;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //二進制轉字符
    public static String toHex(byte[] buf) {
        if (buf == null)
            return "";
        StringBuffer result = new StringBuffer(2 * buf.length);
        for (int i = 0; i < buf.length; i++) {
            appendHex(result, buf[i]);
        }
        return result.toString();
    }

    private static void appendHex(StringBuffer sb, byte b) {
        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
    }
  // 對密鑰進行處理
    private static Key getRawKey(String key) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
        //for android
        SecureRandom sr = null;
        // 在4.2以上版本中,SecureRandom獲取方式發生了改變
        if (android.os.Build.VERSION.SDK_INT >= 17) {
            sr = SecureRandom.getInstance(SHA1PRNG, "Crypto");
        } else {
            sr = SecureRandom.getInstance(SHA1PRNG);
        }
        // for Java
        // secureRandom = SecureRandom.getInstance(SHA1PRNG);
        sr.setSeed(key.getBytes());
        kgen.init(64, sr); //DES固定格式爲64bits,即8bytes。
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return new SecretKeySpec(raw, ALGORITHM);
    }
/**
     * DES算法,加密
     *
     * @param data 待加密字符串
     * @param key  加密私鑰,長度不能夠小於8位
     * @return 加密後的字節數組,一般結合Base64編碼使用
     */
    public static String encode(String key, String data) {
        return encode(key, data.getBytes());
    }


    /**
     * DES算法,加密
     *
     * @param data 待加密字符串
     * @param key  加密私鑰,長度不能夠小於8位
     * @return 加密後的字節數組,一般結合Base64編碼使用
     */
    public static String encode(String key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(IVPARAMETERSPEC.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, getRawKey(key), iv);
            byte[] bytes = cipher.doFinal(data);
            return Base64.encodeToString(bytes, Base64.DEFAULT);
        } catch (Exception e) {
            return null;
        }
    }
  /**
     * 獲取編碼後的值
     *
     * @param key
     * @param data
     * @return
     */
    public static String decode(String key, String data) {
        return decode(key, Base64.decode(data, Base64.DEFAULT));
    }

    /**
     * DES算法,解密
     *
     * @param data 待解密字符串
     * @param key  解密私鑰,長度不能夠小於8位
     * @return 解密後的字節數組
     */
    public static String decode(String key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(IVPARAMETERSPEC.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, getRawKey(key), iv);
            byte[] original = cipher.doFinal(data);
            String originalString = new String(original);
            return originalString;
        } catch (Exception e) {
            return null;
        }
    }

DES知識擴展:3DES

3DES是DES加密算法的一種模式,它使用3條64位的密鑰對數據進行三次加密。數據加密標準(DES)是美國的一種由來已久的加密標準,它使用對稱密鑰加密法。3DES(即Triple DES)是DES向AES過渡的加密算法(1999年,NIST將3-DES指定爲過渡的加密標準),是DES的一個更安全的變形。它以DES爲基本模塊,通過組合分組方法設計出分組加密算法。

DES與AES比較:

當時被問起採用DES加密內心深處我是拒絕的。單純從名字上看AES(Advanced Encryption Standard)高級加密標準,安全性要高於DES,其實AES的出現本身就是爲了取代DES的,AES具有比DES更好的安全性、效率、靈活性,所以對稱加密優先採用AES。

RSA加密

RSA加密算法是一種非對稱加密算法,非對稱加密算法需要兩個密鑰:公共密鑰和私有密鑰。公鑰和私鑰是配對的,用公鑰加密的數據只有配對的私鑰才能解密。

RSA對加密數據的長度有限制,一般爲密鑰的長度值-11,要加密較長的數據,可以採用數據截取的方法,分段加密。

特點是加密速度比較慢,但是安全性比較高;

使用場景:

文件或數據在本地使用公鑰或私鑰加密,加密後的數據傳送到服務器,服務器使用同一套密鑰中的私鑰或者公鑰進行解密。

public class RSAUtils {
    //構建Cipher實例時所傳入的的字符串,默認爲"RSA/NONE/PKCS1Padding"
    private static String sTransform = "RSA/NONE/PKCS1Padding";

    //進行Base64轉碼時的flag設置,默認爲Base64.DEFAULT
    private static int sBase64Mode = Base64.DEFAULT;
    //初始化方法,設置參數
    public static void init(String transform,int base64Mode){
        sTransform = transform;
        sBase64Mode = base64Mode;
    }
    //產生密鑰對
    public static KeyPair generateRSAKeyPair(int keyLength){
        KeyPair keyPair=null;
        try {
            KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
            //設置密鑰長度
            keyPairGenerator.initialize(keyLength);
            //產生密鑰對
            keyPair=keyPairGenerator.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keyPair;
    }

    /**
     * 加密或解密數據的通用的方法,srcData:待處理的數據;key:公鑰或者私鑰,mode指
     * 加密還是解密,值爲Cipher.ENCRYPT_MODE或者Cipher.DECRYPT_MODE
     */
    public static byte[]processDAta(byte[]srcData, Key key,int mode){
        //用來保存處理的結果
        byte[]resultBytes=null;
        //構建Cipher對象,需要傳入一個字符串,格式必須爲"algorithm/mode/padding"或者"algorithm/",意爲"算法/加密模式/填充方式"
        try {
            Cipher cipher=Cipher.getInstance("RSA/NONE/PKCS1Padding");
            //初始化Cipher,mode指定是加密還是解密,key爲公鑰或密鑰
            cipher.init(mode,key);
            //處理數據
            resultBytes=cipher.doFinal(srcData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultBytes;
    }
    //使用公鑰加密數據,結果用Base64轉碼
    public static String encryptDataByPublicKey(byte[]srcData, PublicKey publicKey){
        byte[]resultBytes=processDAta(srcData,publicKey,Cipher.ENCRYPT_MODE);
        return Base64.encodeToString(resultBytes,sBase64Mode);
    }
    //使用私鑰解密,結果用Base64轉碼
    public static byte[]decryptDataByPrivate(String encryptedData, PrivateKey privateKey){
        byte[]bytes=Base64.decode(encryptedData,sBase64Mode);
        return processDAta(bytes,privateKey,Cipher.DECRYPT_MODE);
    }

    //使用私鑰解密,返回解碼數據
    public static String decryptToStrByPrivate(String encryptedData,PrivateKey privateKey){
        return new String(decryptDataByPrivate(encryptedData,privateKey));
    }

}

總結

(1) 對稱加密加密與解密使用的是同樣的密鑰,所以速度快,但由於需要將密鑰在網絡傳輸,所以安全性不高。

(2) 非對稱加密使用了一對密鑰,公鑰與私鑰,所以安全性高,但加密與解密速度慢。

(3) 解決的辦法是將對稱加密的密鑰使用非對稱加密的公鑰進行加密,然後發送出去,接收方使用私鑰進行解密得到對稱加密的密鑰,然後雙方可以使用對稱加密來進行溝通。

使用

在Android開發中,一般只用到Base64,MD5,RSA,DES。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章