2016-04-19 24 views
2

これは私の最初のJavaプロジェクトです。私はAESを使って簡単なテキスト暗号化ツールを作ることにしました。JavaのシンプルなAES暗号化ツール

私は取得していますエラーは次のとおりです。事前に

import java.nio.file.Files; 
import java.nio.file.Paths; 
import java.security.Key; 

import javax.crypto.*; 
import java.util.*; 

public class Encryptor { 

    public static void main(String[] args) throws Exception { 
     String FileName = "encryptedtext.txt"; 
     String FileName2 = "decryptedtext.txt"; 

     Scanner input = new Scanner(System.in); 

     System.out.println("Enter your 16 character key here:"); 
     String EncryptionKey = input.next(); 



     KeyGenerator KeyGen = KeyGenerator.getInstance("AES"); 
     KeyGen.init(128); 

     Cipher AesCipher = Cipher.getInstance("AES"); 

     System.out.println("Enter text to encrypt or decrypt:"); 
     String Text = input.next(); 

     System.out.println("Do you want to encrypt or decrypt (e/d)"); 
     String answer = input.next(); 
     if (answer.equalsIgnoreCase("e")){ 

      byte[] byteKey = (EncryptionKey.getBytes()); 
      byte[] byteText = (Text).getBytes(); 

      AesCipher.init(Cipher.ENCRYPT_MODE, byteKey); // ERROR LINE 
      byte[] byteCipherText = AesCipher.doFinal(byteText); 
      Files.write(Paths.get(FileName), byteCipherText); 


       } 
     else if (answer.equalsIgnoreCase("d")){ 

      byte[] byteKey = (EncryptionKey.getBytes()); 
      byte[] byteText = (Text).getBytes(); 
      byte[] cipherText = Files.readAllBytes(Paths.get(FileName)); 

      AesCipher.init(Cipher.DECRYPT_MODE, byteKey); // ERROR LINE 
      byte[] bytePlainText = AesCipher.doFinal(cipherText); 
      Files.write(Paths.get(FileName2), bytePlainText); 
     } 
} 

} 

ありがとう:暗号引数(int, byte[])

コードには適用されませんタイプのメソッドinit(int, Key)! :)

+1

farily良いサンプルがここにありますhttp://stackoverflow.com/questions/15554296/simple-java-aes-encrypt-decrypt-example 。 命名規則にはキャメルケースを使用してください。:) – GPI

+0

あなたの最初のJavaプロジェクトですが、このプロジェクトの最初の単体テストを書くようにしてください:) –

+0

一般的なアドバイス:**完全な暗号文字列を使用してください** 'Cipher.getInstance(" AES ");' mayデフォルトのセキュリティプロバイダに応じて異なる暗号が生成されます。おそらく '' AES/ECB/PKCS5Padding ''という結果になるでしょうが、必ずしもそうである必要はありません。変更すると、異なるJVM間の互換性が失われます。 –

答えて

0

バイト配列をCipherオブジェクトに直接渡すべきではなく、SecretKeySpecsのオブジェクトを作成する必要があります。

これはこれは

完全なコードのフルコードである完全なコード

import java.nio.file.Files; 
    import java.nio.file.Paths; 
    import javax.crypto.*; 
    import javax.crypto.spec.IvParameterSpec; 
    import javax.crypto.spec.SecretKeySpec; 

    import java.util.*; 

    public class Encrypter { 

    public static void main(String[] args) throws Exception { 
    String FileName = "encryptedtext.txt"; 
    String FileName2 = "decryptedtext.txt"; 

    Scanner input = new Scanner(System.in); 

    System.out.println("Enter your 16 character key here:"); 
    String EncryptionKey = input.next(); 
    byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 
    IvParameterSpec ivspec = new IvParameterSpec(iv); 


    KeyGenerator KeyGen = KeyGenerator.getInstance("AES"); 
    KeyGen.init(128); 


    Cipher AesCipher = Cipher.getInstance("AES/CFB/NoPadding"); 
    System.out.println("Enter text to encrypt or decrypt:"); 
    String Text = input.next(); 

    System.out.println("Do you want to encrypt or decrypt (e/d)"); 
    String answer = input.next(); 
    if (answer.equalsIgnoreCase("e")) { 

    byte[] byteKey = (EncryptionKey.getBytes()); 
    byte[] byteText = (Text).getBytes(); 
    SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "AES"); 
    AesCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec); 
    AesCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec); // ERROR LINE 
    byte[] byteCipherText = AesCipher.doFinal(byteText); 
    Files.write(Paths.get(FileName), byteCipherText); 


    } else if (answer.equalsIgnoreCase("d")) { 

    byte[] byteKey = (EncryptionKey.getBytes()); 
    byte[] byteText = (Text).getBytes(); 
    byte[] cipherText = Files.readAllBytes(Paths.get(FileName)); 

    SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "AES"); 
    AesCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivspec); // ERROR LINE 
    byte[] bytePlainText = AesCipher.doFinal(cipherText); 
    Files.write(Paths.get(FileName2), bytePlainText); 
    } 
} 

} 
+0

ありがとうございました:pスペースを含むテキストを入力すると、e/dをクリックできません。dを選択すると(1単語しか入力しなかった場合)、次のようになります。 スレッド "main" javax.cryptoの例外。 IllegalBlockSizeException:パディングされた暗号で復号化する場合、入力長は16の倍数でなければならない@Prashant –

+0

これを使用 暗号AesCipher = Cipher.getInstance( "AES/CFB/NoPadding"); aescipherのオブジェクトを作成中。 – Prashant

+0

復号化時にまだエラーが発生しています:スレッド「main」の例外java.security.InvalidKeyException:パラメータがありません そして、スペース "テスト"は問題ありませんが、 "テストテスト"を書くと私はe/dを押すことができません よろしく、 –

1

です:

import java.nio.file.Files; 
import java.nio.file.Paths; 
import javax.crypto.*; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

import java.util.*; 

public class Encrypter { 

public static void main(String[] args) throws Exception { 
    String FileName = "encryptedtext.txt"; 
    String FileName2 = "decryptedtext.txt"; 

    Scanner input = new Scanner(System.in); 

    System.out.println("Enter your 16 character key here:"); 
    String EncryptionKey = input.next(); 
    byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 
    IvParameterSpec ivspec = new IvParameterSpec(iv); 


    KeyGenerator KeyGen = KeyGenerator.getInstance("AES"); 
    KeyGen.init(128); 


    Cipher AesCipher = Cipher.getInstance("AES/CFB/NoPadding"); 
    System.out.println("Enter text to encrypt or decrypt:"); 
    String Text = input.next(); 

    System.out.println("Do you want to encrypt or decrypt (e/d)"); 
    String answer = input.next(); 
    if (answer.equalsIgnoreCase("e")){ 

     byte[] byteKey = (EncryptionKey.getBytes()); 
     byte[] byteText = (Text).getBytes(); 
     SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "AES"); 
     AesCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec,ivspec); 
     AesCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec,ivspec); // ERROR LINE 
     byte[] byteCipherText = AesCipher.doFinal(byteText); 
     Files.write(Paths.get(FileName), byteCipherText); 


      } 
    else if (answer.equalsIgnoreCase("d")){ 

     byte[] byteKey = (EncryptionKey.getBytes()); 
     byte[] byteText = (Text).getBytes(); 
     byte[] cipherText = Files.readAllBytes(Paths.get(FileName)); 

     SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "AES"); 
     AesCipher.init(Cipher.DECRYPT_MODE, secretKeySpec,ivspec); // ERROR LINE 
     byte[] bytePlainText = AesCipher.doFinal(cipherText); 
     Files.write(Paths.get(FileName2), bytePlainText); 
    } 
} 

} 
0

私は、外部リンクで公開されてのためのURLを暗号化しなければならなかった、と私は持っていますAESで暗号化するクラスを作成しました。多分、これは誰かを助けることができます。 ランダム初期ベクトルを作成するメソッドを追加しました。このクラスにもあります。

package br.com.tokiomarine.captcha.encryption; 

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

import org.apache.commons.codec.binary.Base64; 
import org.apache.commons.text.CharacterPredicates; 
import org.apache.commons.text.RandomStringGenerator; 

public class Encryptor 
{ 
    public static String encrypt(String key, String initVector, String value) throws Exception 
    { 
     IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8")); 
     SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); 

     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); 
     cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); 

     byte[] encrypted = cipher.doFinal(value.getBytes()); 

     return Base64.encodeBase64URLSafeString(encrypted); 
    } 

    public static String decrypt(String key, String initVector, String encrypted) throws Exception 
    { 
     IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8")); 
     SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); 

     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); 
     cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); 

     byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted)); 

     return new String(original); 
    } 

    public static String generateInitVector() { 
    RandomStringGenerator randomStringGenerator = 
     new RandomStringGenerator.Builder() 
      .withinRange('0', 'z') 
      .filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS) 
      .build(); 
    return randomStringGenerator.generate(16); 
    } 

} 

そして、ここに私のテストクラスである:

public class EcryptionTest { 

    @Test 
    public void encryptionTest() { 
     try 
     { 
      String key = "[email protected]"; 
      for(int i = 0; i < 1000; i++) 
      { 
       String initVector = Encryptor.generateInitVector(); 
       String encrypted = Encryptor.encrypt(key, initVector, "StringTeste"); 
       assertTrue("StringTeste".equals(Encryptor.decrypt(key, initVector, encrypted))); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

}