2016-04-19 4 views
2

Это мой первый проект на Java, и я решил сделать простой текстовый шифр с использованием AES.Простой AES-шифр в Java

Ошибка я получаю: метод init(int, Key) в типе Cipher не применяется для аргументов (int, byte[])

Код:

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); 
     } 
} 

} 

Спасибо заранее! :)

+1

Есть farily хорошие образцы здесь: http://stackoverflow.com/questions/15554296/simple-java-aes-encrypt-decrypt-example , Пожалуйста, используйте футляр для верблюда для ваших соглашений об именах, это помогает :). – GPI

+0

его первый проект java, кстати, попробуйте написать свой первый модульный тест для этого проекта :) –

+0

Общий совет: ** Всегда используйте полностью квалифицированную строку Cipher. ** 'Cipher.getInstance (« AES »); приводят к разным шифрам в зависимости от поставщика безопасности по умолчанию. Это, скорее всего, приводит к '' 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

использовать это Cipher AesCipher = Cipher.getInstance («AES/CFB/NoPadding»); при создании объекта aescipher.Click on accept answer button, если он вам помог – 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. Может быть, это может помочь кому-то. Я добавил метод создания моего Random Initial Vector, который также находится в этом классе.

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(); 
     } 
    } 

} 
Смежные вопросы