Android対称暗号化と非対称暗号化


シーザーパスワード
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     char
int 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 + "     " + "
"); 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、3 DS、TDEA、Blowfish、RC 2、RC 4、RC 5、IDEA、SKIPJACKなどです。
DES:すべてData Ecrypection Standardと呼ばれ、つまりデータ暗号化の標準は鍵を使って暗号化されたブロックアルゴリズムであり、1976年に米連邦政府の国家標準局に連邦資料処理標準(FIPS)が定められ、その後国際的に広く普及した。
3 DS:Triple_DESともいいます。三重データ暗号アルゴリズム(TDEA、Triple Data Ecryption Algorithm)ブロックのパスワードの通称です。
これは相当しており、各データブロックに3回のDES暗号化アルゴリズムを適用する。コンピュータ演算能力の増強により、オリジナルDES暗号の鍵長は暴力的に解読されやすくなる。3 DSとは、新しいブロック暗号アルゴリズムを設計するのではなく、DESの鍵長を増加させることによって類似の攻撃を回避する比較的簡単な方法を提供するために設計されたものである。
AES:高級暗号化規格(英語:Advanced Ecryption Standard、略語:AES)は、暗号学ではRijdael暗号化法とも呼ばれ、米連邦政府が採用しているブロック暗号化の基準です。この標準はもとのDESに取って代わるために用いて、すでに多方面に分析されてしかも全世界のために使われました。五年間のオーディションプロセスを経て、高級暗号化基準は米国国家規格と技術研究院(NIST)が2001年11月26日にFIPS PUB 197に発表し、2002年5月26日に有効な基準となりました。2006年、高級暗号化規格は対称鍵暗号の中で最も人気のあるアルゴリズムの一つとなりました。
DESアルゴリズムの概要
DES暗号化の原理(ビットを比較して操作し、交換位置、異種などを詳細に知る必要はない)
知識を用意する
Bitはコンピュータの最小転送単位である。ビットの値を0または1で表します。
例えば、数字3に対応するバイナリデータは、0000011です。
コードの例

 int i = 97;
 String bit = Integer.toBinaryString(i);
 //  :97          : 1100001
 System.out.println(i + "         : " + bit);

BytteとBitの違い
データストアは「バイト」(Byte)単位であり、データ転送は多くが「ビット」(bit、別名「ビット」)単位であり、1ビットは1つの0または1(即ちバイナリ)を表し、8ビット(bit、略字はb)ごとに1バイト(Byte、略字はB)を構成し、最少級の情報単位である。
Bytteの取得範囲:

//byte      :-128  127
System.out.println(Byte.MIN_VALUE + " " + Byte.MAX_VALUE);

つまり、1000000から01111111までの間に、1バイトは8ビットを占めます。
バイナリ回転10進数図:
这里写图片描述
どの文字列もバイト配列に変換できます。

String data = "1234abcd";
byte[] bytes = data.getBytes();//   :49 50 51 52 97 98 99 100
上記データ49 50 51 52 97 98 99 100に対応するバイナリデータ(すなわちビットビット数):
0010001
0010010
0010011
0010100
0110001
011000110
011000111
01100100
彼らの間隔を大きくすると、行列として見なされます。
0 0 1 1 0 0 0 1 1
0 0 1 1 0 1 0 1 0 1 0 0 0 1 0
0 0 1 1 0 0 1 1 1 1
0 0 1 1 0 1 0 0 0
0 1 1 0 0 0 0 1
0 1 1 0 0 1 0 0 1 0 0 0 1 0
0 1 1 0 0 0 1 1
0 1 1 0 1 0 1 0 0 0 0
その後、交換位置、分割、異種演算など、彼らに対して様々な動作を行うことができ、一般的な暗号化方式はこのようにビットビットを操作する。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。