2016-12-29 12 views
2

免責事項、私はAndroidで暗号化を行ってきたiOS開発者です。それは私がAndroidで暗号化を達成するのを助けてきましたが、データの暗号化と復号化の単体テストはどうでしょうか?Javaでの暗号化と復号化のユニットテスト

今すぐ頭に浮かぶ最初のアイデアは、のようになります。

String encryptedInputData = encryptedInputData("Hello"); 
String decryptedData = decryptData(encryptedInputData); 
Assert.assertEquals(decryptedData,"Hello"); 

このテストでは、しかし、1つの欠陥をもたらす何かがencryptedInputDatadecryptData方法の変更を行った場合は...、このテストは何を伝えていないだろう変更され、なぜそれが現在壊れているのでしょうか。だから私ははるかに細かいテストを書いてみたいです。たとえば、このコードを与えられたので:

Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding"); 
cipher.init(Cipher.ENCRYPT_MODE, key); 
byte[] data = cipher.doFinal(message); 

私はcipher変数が無いパディングをECBモードでのRSAアルゴリズムを使用していることを確認したいと思います。私は今、私は私がCipherクラスをモックすることができるだろう想像

.doFinal(message)message等、特定のフォーマットに従うことをテストしたいのですが、ここでの問題が書かれた暗号化と復号化には、働くことがありますUtilクラスとしてのみ、これを単体テストできるようにするためには、私はCipherというモックをコードに渡す必要があります。これはUtilクラスであると考えられます。つまり、initメソッドを作成する必要があります。 単体テスト目的の場合は、単体テストの場合はセッターメソッドを作成してください。私はコードを単体テストすることができますが、Utilクラスは実際には生産目的では必要のないコードでは厄介です。

このような単体テストシナリオを実行するための優雅な方法はありますか?すなわちencryptedInputDatadecryptDataはパブリックメソッドですが、これらのメソッドは、単体テストである必要があるさまざまなプライベートメソッドを使用します。

答えて

2

本物の答えは必要ありません。独自の暗号化ルーチンを実装するべきではありません。あなたが間違っている可能性が高いだけでなく、実装上の問題のために実際にハッキング可能でないことを確認するために必要な非常に複雑なことがあります(たとえば、if文の1つのブランチが、小切手の価値が何であるか把握することができます)。あなたは常に、よく見直されたオープンソースのライブラリを使用するべきです。

自分で実装しているわけではないので、単体テストする必要はありません。図書館の作家はそうすべきです。あなたがそれが好きなら、自分のテストスイートを自分の一環として走らせてください。しかし、リリース前にそれをやったのは時間の無駄だと思っています。

0

ガベは正確にであることについての彼の答えに正しいですホイールを再発明するときに控えめである;特に、その車輪が暗号/セキュリティ/そのようなものについてであるとき。チャンスはあなたが間違っていることです。そして、ハッカーを愛している人々は、独自の "安全な暗号化"を持ってきています。

実際の質問にお答えします:TDD(テスト駆動開発)と一緒にお試しください。あなたの問題は、テストするのが難しいAPIをいくつか作成したことです。

あなたは正しいですが、decrypt(encrypt( "something"))に "something"が付いていることを確認するテストのように、 "end to end"が必要です。あなたの問題は次のようなものです。 ユニットテストは難しいです。

したがって、最初から、「どのクラスが私に必要なのか」を考えてみると、 「どのメソッドがどのクラスに入るか」に焦点を当てる必要があり、どのようにそれをテストするのですか?

つまり、テストすることができるユニットを実際に設計する必要があるため、これはTDDが非常に重要な機会の1つです。そしてそこに到達するベストプラクティスは、まずテストを書くことです。テストを行うことができるようにユニットを設計する場合(最初にテストを書いたからです)。驚き - テストすることができます。事実の後にそれらを「テスト可能」にすることは、常に面倒です。ほとんどの場合、不可能に近い。

0

Cipherは、javax.cryptoclassにあります。だからあなたはそれを嘲笑する必要はありません。

1. Keyが正しく生成され、要件を満たしていることを確認するために単体テストを書くことができます。 2. CipherInputStreamが正常に作成されました。ファイルおよび復号化した後、それを読んだことは一致しないために 3.テキストのコピー:

@Test 
public void streamEncryptionDecryptionTest() { 

    try { 
     File file = tempFolder.newFile("test.txt"); 

     String content = "This is the text content"; 
     System.out.println("Original content for file = " + content); 


     OutputStream fop = new FileOutputStream(file); 

     byte[] key = EncryptionHelper.createKey(); 

     fop = EncryptionHelper.getInstance(key).getEncryptedOutputStream(fop); 

     // if file doesn't exists, then create it 
     if (!file.exists()) { 
      file.createNewFile(); 
     } 

     // get the content in bytes 
     byte[] contentInBytes = content.getBytes(); 

     fop.write(contentInBytes); 
     fop.flush(); 
     fop.close(); 

     System.out.println("Encryption Done"); 

     { // Read content w/o decryption 
      InputStream fis = new FileInputStream(file); 
      System.out.println("Content w/o decryption"); 

      int contentChars; 
      while ((contentChars = fis.read()) != -1) { 
       // convert to char and display it 
       System.out.print((char) contentChars); 
      } 

     } 

     { // Decrypted content 
      InputStream fis = new FileInputStream(file); 
      fis = EncryptionHelper.getInstance(key).getDecryptedInputStream(fis); 

      System.out.println("Total file size to read (in bytes) : " 
        + fis.available()); 

      System.out.println("Decrypted content"); 

      int contentChars; 
      while ((contentChars = fis.read()) != -1) { 
       // convert to char and display it 
       System.out.print((char) contentChars); 
      } 
     } 


    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Assert.assertTrue("security exception", false); 
    } 
} 

そのテストは、明示的なアサーションチェックを持っていませんが、あなたが追加することができます。

for (int i = 0; i < buffer.length; i++) { 
    byte b = buffer[i]; 
    System.out.print(b); 
    decryptedContent[i] = b; 
} 

をして、配列を確認してください。

Assert.assertArrayEquals(bytesEncoded, decryptedContent); 

バイト配列を文字列に変換して比較しないでください。間違った実装が行われるためです。

  1. 部分的なバッファ暗号化と復号化が適切に機能しています。あなたのニーズに応じて。