Android對稱式加密與非對稱式加密_Android

來源:互聯網
上載者:User

凱撒密碼

1. 介紹

凱撒密碼作為一種最為古老的對稱式加密體制,在古羅馬的時候都已經很流行,他的基本思想是:通過把字母移動一定的位元來實現加密和解密。明文中的所有字母都在字母表上向後(或向前)按照一個固定數目進行位移後被替換成密文。例如,當位移量是3 的時候,所有的字母A 將被替換成D,B 變成E,由此可見,位元就是凱撒密碼加密和解密的密鑰。

例如:字串”ABC”的每個字元都右移3 位則變成”DEF”,解密的時候”DEF”的每個字元左移3 位即能還原,如下圖所示:

2. 準備知識

 //字元轉換成ASCII 碼數值 char charA = 'a'; int intA = charA; //char 強轉為int 即得到對應的ASCII 碼值,'a'的值為97//ASCII 碼值轉成charint intA = 97;//97 對應的ASCII 碼'a'char charA = (char) intA; //int 值強轉為char 即得到對應的ASCII 字元,即'a'

3. 凱撒密碼的簡單代碼實現

 /**   * 加密   * @param input 資料來源(需要加密的資料)   * @param key 秘鑰,即位移量   * @return 返回加密後的資料   */  public static String encrypt(String input, int key) {    //得到字串裡的每一個字元    char[] array = input.toCharArray();    for (int i = 0; i < array.length; ++i) {      //字元轉換成ASCII 碼值      int ascii = array[i];      //字元位移,例如a->b      ascii = ascii + key;      //ASCII 碼值轉換為char      char newChar = (char) ascii;      //替換原有字元      array[i] = newChar;      //以上4 行代碼可以簡寫為一行      //array[i] = (char) (array[i] + key);    }    //字元數群組轉換成String    return new String(array);  }  /**   * 解密   * @param input 資料來源(被加密後的資料)   * @param key 秘鑰,即位移量   * @return 返回解密後的資料   */  public static String decrypt(String input, int key) {    //得到字串裡的每一個字元    char[] array = input.toCharArray();    for (int i = 0; i < array.length; ++i) {      //字元轉換成ASCII 碼值      int ascii = array[i];      //恢複字元位移,例如b->a      ascii = ascii - key;      //ASCII 碼值轉換為char      char newChar = (char) ascii;      //替換原有字元      array[i] = newChar;      //以上4 行代碼可以簡寫為一行      //array[i] = (char) (array[i] - key);    }    //字元數群組轉換成String    return new String(array);  }

代碼輸出結果:

4. 破解凱撒密碼:頻率分析法

凱撒密碼加密強度太低,只需要用頻度分析法即可破解。
在任何一種書面語言中,不同的字母或字母組合出現的頻率各不相同。而且,對於以這種語言書寫的任意一段文本,都具有大致相同的特徵字母分布。比如,在英語中,字母E 出現的頻率很高,而X 則出現得較少。

英語文本中典型的字母分布情況如下圖所示:

5. 破解流程

統計密文裡出現次數最多的字元,例如出現次數最多的字元是是'h'。

計算字元'h'到'e'的位移量,值為3,則表示原文位移了3 個位置。

將密文所有字元恢複位移3 個位置。

注意點:統計密文裡出現次數最多的字元時,需多統計幾個備選,因為最多的可能是空格或者其他字元,例如下圖出現次數最多的字元'#'是空格加密後的字元,'h'才是'e'位移後的值。

解密時要多幾次嘗試,因為不一定出現次數最多的字元就是我們想要的目標字元,如下圖,第二次解密的結果才是正確的。

/** * 頻率分析法破解凱撒密碼 */public class FrequencyAnalysis {  //英文裡出現次數最多的字元  private static final char MAGIC_CHAR = 'e';  //破解產生的最大檔案數  private static final int DE_MAX_FILE = 4;  public static void main(String[] args) throws Exception {    //測試1,統計字元個數    //printCharCount("article1_en.txt");    //加密檔案    //int key = 3;    //encryptFile("article1.txt", "article1_en.txt", key);    //讀取加密後的檔案    String artile = file2String("article1_en.txt");    //解密(會產生多個備選檔案)    decryptCaesarCode(artile, "article1_de.txt");  }  public static void printCharCount(String path) throws IOException{    String data = file2String(path);    List<Entry<Character, Integer>> mapList = getMaxCountChar(data);    for (Entry<Character, Integer> entry : mapList) {      //輸出前幾位的統計資訊      System.out.println("字元'" + entry.getKey() + "'出現" + entry.getValue() + "次");    }  }  public static void encryptFile(String srcFile, String destFile, int key) throws IOException {    String artile = file2String(srcFile);    //加密檔案    String encryptData = MyEncrypt.encrypt(artile, key);    //儲存加密後的檔案    string2File(encryptData, destFile);  }  /**   * 破解凱撒密碼   * @param input 資料來源   * @return 返回解密後的資料   */  public static void decryptCaesarCode(String input, String destPath) {    int deCount = 0;//當前解密產生的備選檔案數    //擷取出現頻率最高的字元資訊(出現次數越多越靠前)    List<Entry<Character, Integer>> mapList = getMaxCountChar(input);    for (Entry<Character, Integer> entry : mapList) {      //限制解密檔案備選數      if (deCount >= DE_MAX_FILE) {        break;      }      //輸出前幾位的統計資訊      System.out.println("字元'" + entry.getKey() + "'出現" + entry.getValue() + "次");      ++deCount;      //出現次數最高的字元跟MAGIC_CHAR的位移量即為秘鑰      int key = entry.getKey() - MAGIC_CHAR;      System.out.println("猜測key = " + key + ", 解密產生第" + deCount + "個備選檔案" + "\n");      String decrypt = MyEncrypt.decrypt(input, key);      String fileName = "de_" + deCount + destPath;      string2File(decrypt, fileName);    }  }  //統計String裡出現最多的字元  public static List<Entry<Character, Integer>> getMaxCountChar(String data) {    Map<Character, Integer> map = new HashMap<Character, Integer>();    char[] array = data.toCharArray();    for (char c : array) {      if(!map.containsKey(c)) {        map.put(c, 1);      }else{        Integer count = map.get(c);        map.put(c, count + 1);      }    }    //輸出統計資訊    /*for (Entry<Character, Integer> entry : map.entrySet()) {      System.out.println(entry.getKey() + "出現" + entry.getValue() + "次");    }*/    //擷取擷取最大值    int maxCount = 0;    for (Entry<Character, Integer> entry : map.entrySet()) {      //不統計空格      if (/*entry.getKey() != ' ' && */entry.getValue() > maxCount) {         maxCount = entry.getValue();      }    }    //map轉換成list便於排序    List<Entry<Character, Integer>> mapList = new ArrayList<Map.Entry<Character,Integer>>(map.entrySet());    //根據字元出現次數排序    Collections.sort(mapList, new Comparator<Entry<Character, Integer>>(){      @Override      public int compare(Entry<Character, Integer> o1,          Entry<Character, Integer> o2) {        return o2.getValue().compareTo(o1.getValue());      }    });    return mapList;  }  public static String file2String(String path) throws IOException {    FileReader reader = new FileReader(new File(path));    char[] buffer = new char[1024];    int len = -1;    StringBuffer sb = new StringBuffer();    while ((len = reader.read(buffer)) != -1) {      sb.append(buffer, 0, len);    }    return sb.toString();  }  public static void string2File(String data, String path){    FileWriter writer = null;    try {      writer = new FileWriter(new File(path));      writer.write(data);    } catch (Exception e) {      e.printStackTrace();    }finally {      if (writer != null) {        try {          writer.close();        } catch (IOException e) {          e.printStackTrace();        }      }    }  }}

對稱式加密

介紹

加密和解密都使用同一把秘鑰,這種加密方法稱為對稱式加密,也稱為單祕密金鑰加密。
簡單理解為:加密解密都是同一把鑰匙。
凱撒密碼就屬於對稱式加密,他的字元位移量即為秘鑰。

對稱式加密常用演算法

AES、DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK 等。

DES:全稱為Data Encryption Standard,即資料加密標準,是一種使用祕密金鑰加密的塊演算法,1976 年被美國聯邦政府的國家標準局確定為聯邦資料處理標準(FIPS),隨後在國際上廣泛流傳開來。

3DES:也叫Triple DES,是三重資料加密演算法(TDEA,Triple Data Encryption Algorithm)塊密碼的通稱。
它相當於是對每個資料區塊應用三次DES 密碼編譯演算法。由於電腦運算能力的增強,原版DES 密碼的密鑰長度變得容易被暴力破解;3DES 即是設計用來提供一種相對簡單的方法,即通過增加DES 的密鑰長度來避免類似的攻擊,而不是設計一種全新的塊密碼演算法。

AES: 進階加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael 加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,進階加密標準由美國國家標準與技術研究院(NIST)於2001 年11 月26 日發佈於FIPS PUB 197,並在2002 年5 月26 日成為有效標準。2006 年,進階加密標準已然成為對稱金鑰密碼編譯中最流行的演算法之一。

DES 演算法簡介

DES 加密原理(對位元位進行操作,交換位置,異或等等,無需詳細瞭解)

準備知識

Bit 是電腦最小的傳輸單位。以0 或1 來表示位元位的值
例如數字3 對應的位元據為:00000011

程式碼範例

 int i = 97; String bit = Integer.toBinaryString(i); //輸出:97 對應的位元據為: 1100001 System.out.println(i + "對應的位元據為: " + bit);

Byte 與Bit 區別

資料存放區是以“位元組”(Byte)為單位,資料轉送是以大多是以“位”(bit,又名“位元”)為單位,一個位就代表一個0 或1(即二進位),每8 個位(bit,簡寫為b)組成一個位元組(Byte,簡寫為B),是最小一級的資訊單位。

Byte 的取值範圍:

//byte 的取值範圍:-128 到127System.out.println(Byte.MIN_VALUE + "到" + Byte.MAX_VALUE);

即10000000 到01111111 之間,一個位元組佔8 個位元位

二進位轉十進位圖示:

任何字串都可以轉換為位元組數組

String data = "1234abcd";byte[] bytes = data.getBytes();//內容為:49 50 51 52 97 98 99 100

上面資料49 50 51 52 97 98 99 100 對應的位元據(即位元位為):

00110001
00110010
00110011
00110100
01100001
01100010
01100011
01100100

將他們間距調大一點,可看做一個矩陣:

0 0 1 1 0 0 0 1
0 0 1 1 0 0 1 0
0 0 1 1 0 0 1 1
0 0 1 1 0 1 0 0
0 1 1 0 0 0 0 1
0 1 1 0 0 0 1 0
0 1 1 0 0 0 1 1
0 1 1 0 0 1 0 0

之後可對他們進行各種操作,例如交換位置、分割、異或運算等,常見的加密方式就是這樣操作位元位的。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.