Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的简易AES加密机_Java_Encryption_Aes - Fatal编程技术网

Java中的简易AES加密机

Java中的简易AES加密机,java,encryption,aes,Java,Encryption,Aes,这是我在Java中的第一个项目,我决定使用AES制作一个简单的文本加密程序 我得到的错误是:类型密码中的方法init(int,Key)不适用于参数(int,byte[]) 代码: 提前感谢!:) 您不应该将字节数组直接传递给Cipher对象,而是需要创建secretKeySpec的对象 这是完整的代码 import java.nio.file.Files; import java.nio.file.Paths; import javax.crypto.*; import java

这是我在Java中的第一个项目,我决定使用AES制作一个简单的文本加密程序

我得到的错误是:类型密码中的方法
init(int,Key)
不适用于参数
(int,byte[])

代码:


提前感谢!:)

您不应该将字节数组直接传递给Cipher对象,而是需要创建secretKeySpec的对象

这是完整的代码

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

}
这是完整的代码

完整代码:

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

}

我必须加密在外部链接中公开的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 = "Key@TokioMarineC";
            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();
        }
    }

}
公共类加密测试{
@试验
public void encryptionTest(){
尝试
{
字符串键=”Key@TokioMarineC";
对于(int i=0;i<1000;i++)
{
字符串initVector=Encryptor.generateInitVector();
String encrypted=Encryptor.encrypt(key,initVector,“StringTeste”);
assertTrue(“StringTeste”.equals(Encryptor.decrypt(key,initVector,encrypted));
}
}捕获(例外e){
e、 printStackTrace();
}
}
}

这里有非常好的示例:。请使用camel-case作为您的命名约定,这很有帮助:)。顺便说一下,这是您的第一个java项目,请尝试为此项目编写第一个单元测试:)一般建议:始终使用完全限定的密码字符串<代码>Cipher.getInstance(“AES”)可能会产生不同的密码。它很可能会导致添加AES/ECB/PKCS5P“,但不必如此。如果它发生更改,您将失去不同JVM之间的兼容性。请不要使用。它是确定性的,因此在语义上不安全。您至少应该使用随机模式,如或。最好是对密文进行身份验证,这样就不可能进行类似的攻击。这可以通过像GCM或EAX这样的认证模式来实现,也可以通过一个方案来实现。感谢您解决了这个问题:p当输入一个包含空格的文本时,我不能单击e/d,当选择d(如果我只输入了1个单词)时,我在线程“main”中得到这个:异常javax.crypto.IllegalBlockSizeException:当使用填充密码@Prashantuse进行解密时,输入长度必须是16的倍数。此密码AESCHERPER=cipher.getInstance(“AES/CFB/NoPadding”);创建AESChipher对象时。如果有帮助,请单击“接受答案”按钮。我在解密时仍然遇到错误:线程“main”java.security.InvalidKeyException中的异常:缺少参数,并且我不能有一个有空格的文本“test”很好,但在编写“test test”时我不能按e/d键,你能检查一下这个链接吗?如果它能正常工作,我会更新代码,给我10分钟。我们需要添加初始化向量,iv。我们可以使用0零向量
public class EcryptionTest {

    @Test
    public void encryptionTest() {
        try 
        {
            String key = "Key@TokioMarineC";
            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();
        }
    }

}