Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.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 尝试解密加密数据时标记不匹配_Java_Encryption - Fatal编程技术网

Java 尝试解密加密数据时标记不匹配

Java 尝试解密加密数据时标记不匹配,java,encryption,Java,Encryption,我正在为我的Java编程类做一个创建密码管理器的项目,我正在加密和解密我的密码 我的加密工作正常,但我一直得到javax.crypto.AEADBadTagException:标记不匹配!错误 以下是全部错误: 线程“main”javax.crypto.AEADBadTagException中出现异常:标记不匹配! 位于java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:5

我正在为我的Java编程类做一个创建密码管理器的项目,我正在加密和解密我的密码

我的加密工作正常,但我一直得到javax.crypto.AEADBadTagException:标记不匹配!错误

以下是全部错误:

线程“main”javax.crypto.AEADBadTagException中出现异常:标记不匹配! 位于java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:580) 位于java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1116) 位于java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1053) 位于java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853) 位于java.base/com.sun.crypto.provider.aesciper.engineDoFinal(aesciper.java:446) 位于java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202) 在PasswordVault.Decrypt(PasswordVault.java:89) 位于PasswordVault.main(PasswordVault.java:27)

我一直试图通过研究来找出我自己的错误,但我并没有太多的运气,也不知道哪里出了问题

这是我的主要课程:

import java.io.UnsupportedEncodingException;
import java.security.*;
import java.util.ArrayList;
import java.util.Scanner;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.util.Base64;

public class PasswordVault {
    private static ArrayList<Password> passwordVault;
    public Scanner keyboard = new Scanner(System.in);
    public String website;
    public String username;
    private String password;
    private SecretKey key;

public static void main(String[] args) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, NoSuchProviderException, InvalidAlgorithmParameterException {
    passwordVault = new ArrayList<>();
    addPassword();
    System.out.println(passwordVault);
    //byte [] passwordByte = passwordVault.get(0).getPassword().getBytes();
    System.out.println(Decrypt(passwordVault.get(0).getPassword(),generateKey()));
}


public static void addPassword() throws NoSuchPaddingException, BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeyException, NoSuchProviderException, InvalidAlgorithmParameterException {
    Scanner keyboard = new Scanner(System.in);
    String website;
    String username;
    String password;
    SecretKey key = null;

    System.out.println("Please enter in the website that you would like to store a password:");
    website = keyboard.nextLine();
    System.out.println("Please enter your username");
    username = keyboard.nextLine();
    System.out.println("Please enter your password");
    password = keyboard.nextLine();
    key = generateKey();
    savePassword(website,username,password,key);
}

private static ArrayList<Password>savePassword(String website, String username, String password, SecretKey key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, NoSuchProviderException, InvalidAlgorithmParameterException {
    String encryptedPassword;
    encryptedPassword = Encrypt(password,key);
    String stringEncryptedPassword = new String(encryptedPassword);
    Password savePass = new Password(website, username, stringEncryptedPassword);
    passwordVault.add(savePass);
    return passwordVault;
}

public static SecretKey generateKey() throws NoSuchPaddingException, NoSuchAlgorithmException {
    SecureRandom random = SecureRandom.getInstanceStrong();
    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    keyGen.init(128, random);
    SecretKey key = keyGen.generateKey();
    return key;
}
private static String Encrypt(String password, SecretKey key) throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchProviderException {
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
    byte[] iv = new byte[12];
    SecureRandom random = SecureRandom.getInstanceStrong();
    random.nextBytes(iv);
    GCMParameterSpec spec = new GCMParameterSpec(128, iv);
    cipher.init(Cipher.ENCRYPT_MODE, key, spec);
    byte [] bytePassword = password.getBytes("UTF-8");
    byte [] encryptedPassword = cipher.doFinal(bytePassword);
    /*Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte [] bytePassword = password.getBytes("UTF-8");
    byte [] encryptedPassword = cipher.doFinal(bytePassword);
    return Base64.getEncoder().encodeToString(encryptedPassword);*/
    //return encryptedPassword;
    return Base64.getEncoder().encodeToString(encryptedPassword);
}

private static String Decrypt(String password, SecretKey key) throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, NoSuchProviderException, InvalidAlgorithmParameterException {
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
    byte[] iv = new byte[12];
    SecureRandom random = SecureRandom.getInstanceStrong();
    random.nextBytes(iv);
    GCMParameterSpec spec = new GCMParameterSpec(128, iv);
    cipher.init(Cipher.DECRYPT_MODE, key, spec);
    return new String(cipher.doFinal(Base64.getDecoder().decode(password)));
}
//byte [] byteDecryptPassword = cipher.doFinal(password);
// String newPassword = new String(password, "UTF-8");
//Cipher cipher = null;
//cipher = Cipher.getInstance("AES/GCM/NoPadding");
//cipher.init(Cipher.DECRYPT_MODE, key);
    /*byte [] bytePassword = new byte[0];
    bytePassword = password.getBytes("UTF-8");
    byte [] encryptedPassword = new byte[0];
    encryptedPassword = cipher.doFinal(bytePassword);*/

}
我现在希望通过测试得到的是我输入的密码的解密纯文本版本。现在,我只是一直受到这个坏消息的困扰


非常感谢您的帮助。

我实际上找到了我程序的解决方案。 我不得不重构东西,因为我认为我一直在重置我的iv,这会导致类型不匹配

这是我完成的工作代码:

import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.util.ArrayList;
import java.util.Scanner;

public class TestPasswordVault {
private static ArrayList<Password> passwordVault;
public Scanner keyboard = new Scanner(System.in);
public String website;
public String username;
private String password;
private static SecretKey key;

public static void main(String[] args) throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchProviderException {
    String test = "kittens";
    SecureRandom random = SecureRandom.getInstanceStrong();
    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    keyGen.init(128, random);
    SecretKey key = keyGen.generateKey();
    byte[] iv = new byte[12];
    random.nextBytes(iv);
    System.out.println(test);
    byte [] newTest = doEncrypt(test,iv,random,key);
    System.out.println(newTest);
    System.out.println(doDecrypt(newTest,iv,random,key));
}


public static byte [] doEncrypt(String password, byte [] iv, SecureRandom random, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
    GCMParameterSpec spec = new GCMParameterSpec(128, iv);
    cipher.init(Cipher.ENCRYPT_MODE, key, spec);
    byte [] encryptPassword = password.getBytes("UTF-8");
    byte[] cipherText = cipher.doFinal(encryptPassword);
    return cipherText;
}

public static String doDecrypt(byte [] encrypted, byte [] iv, SecureRandom random, SecretKey key)throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
    GCMParameterSpec spec = new GCMParameterSpec(128, iv);
    cipher.init(Cipher.DECRYPT_MODE, key, spec);
    byte[] plainText = cipher.doFinal(encrypted);
    return new String(plainText);
}


}
import javax.crypto.*;
导入javax.crypto.spec.gcmpareterspec;
导入java.io.UnsupportedEncodingException;
导入java.security.*;
导入java.util.ArrayList;
导入java.util.Scanner;
公共类TestPasswordVault{
私有静态ArrayList密码库;
公共扫描仪键盘=新扫描仪(System.in);
公共字符串网站;
公共字符串用户名;
私有字符串密码;
私有静态秘密密钥;
public static void main(字符串[]args)引发UnsupportedEncodingException、NoSuchPaddingException、NoSuchAlgorithmException、BadPaddingException、IllegalBlockSizeException、InvalidKeyException、InvalidAlgorithmParameterException、NoSuchProviderException{
字符串测试=“小猫”;
SecureRandom=SecureRandom.getInstanceStrong();
KeyGenerator keyGen=KeyGenerator.getInstance(“AES”);
keyGen.init(128,随机);
SecretKey=keyGen.generateKey();
字节[]iv=新字节[12];
随机。下一字节(iv);
系统输出打印LN(测试);
字节[]newTest=doEncrypt(测试、iv、随机、键);
系统输出打印LN(新测试);
System.out.println(doDecrypt(newTest,iv,random,key));
}
公共静态字节[]doEncrypt(字符串密码、字节[]iv、SecureRandom、SecretKey密钥)抛出NoSuchPaddingException、NoSuchAlgorithmException、NoSuchProviderException、InvalidGorthmParameterException、InvalidKeyException、BadPaddingException、IllegalBlockSizeException、UnsupportedEncodingException{
Cipher Cipher=Cipher.getInstance(“AES/GCM/NoPadding”,“SunJCE”);
GCMParemeterSpec=新的GCMParemeterSpec(128,iv);
cipher.init(cipher.ENCRYPT_模式,密钥,规范);
byte[]encryptPassword=password.getBytes(“UTF-8”);
字节[]密文=cipher.doFinal(encryptPassword);
返回密文;
}
公共静态字符串doDecrypt(字节[]加密,字节[]iv,SecureRandom,SecretKey密钥)抛出NoSuchPaddingException,NoSuchAlgorithmException,NoSuchProviderException,InvalidGorthmParameterException,InvalidKeyException,BadPaddingException,IllegalBlockSizeException,UnsupportedEncodingException{
Cipher Cipher=Cipher.getInstance(“AES/GCM/NoPadding”,“SunJCE”);
GCMParemeterSpec=新的GCMParemeterSpec(128,iv);
cipher.init(cipher.DECRYPT_模式,密钥,规范);
字节[]明文=cipher.doFinal(加密);
返回新字符串(纯文本);
}
}

为了让您了解如何对其进行编程,让我们向您展示一个新的
密码Vault

当然,您自己的新代码片段也可以工作,目前绕过了密码存储所需的设计;这是一个通用的GCM示例,它不存储IV,也没有保险库等等(如果您无法让GCM工作,这可能是一个好主意)

请注意,下面的代码片段仍然不是一个安全的vault,但它展示了如何以OO方式编程故障

import static java.nio.charset.StandardCharsets.UTF_8;

import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Scanner;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;

public class PasswordVault {
    private static final int KEY_SIZE_BITS = 128;
    private static final int GCM_TAG_SIZE_BITS = 128;
    private static final int GCM_IV_SIZE_BYTES = 12;
    private ArrayList<PasswordEntry> vaultBoxes;
    private SecretKey key;

    public PasswordVault() throws NoSuchAlgorithmException {
        vaultBoxes = new ArrayList<>();
        key = generateKey();
    }

    public void encryptAndStorePasswordEntry(PasswordEntry passwordEntry) throws GeneralSecurityException {
        String encryptedPassword = encrypt(passwordEntry.getPassword(), key);
        PasswordEntry savePass = new PasswordEntry(passwordEntry.getWebsite(), passwordEntry.getLogin(),
                encryptedPassword);
        vaultBoxes.add(savePass);
    }

    public PasswordEntry retrieveAndDecryptPasswordEntry() throws GeneralSecurityException {
        // TODO think of a way to retrieve the password for a specific entry
        PasswordEntry encryptedPasswordEntry = vaultBoxes.get(0);
        String password = decrypt(encryptedPasswordEntry.getPassword(), key);
        return new PasswordEntry(encryptedPasswordEntry.getWebsite(), encryptedPasswordEntry.getLogin(), password);
    }

    public static SecretKey generateKey() throws NoSuchAlgorithmException {
        SecureRandom random = SecureRandom.getInstanceStrong();
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(KEY_SIZE_BITS, random);
        return keyGen.generateKey();
    }

    public static String encrypt(String password, SecretKey key) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

        byte[] iv = generateRandomIV();

        GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, spec);

        byte[] bytePassword = password.getBytes(UTF_8);
        byte[] ivCTAndTag = new byte[GCM_IV_SIZE_BYTES + cipher.getOutputSize(bytePassword.length)];
        System.arraycopy(iv, 0, ivCTAndTag, 0, GCM_IV_SIZE_BYTES);

        cipher.doFinal(bytePassword, 0, bytePassword.length, ivCTAndTag, GCM_IV_SIZE_BYTES);

        return Base64.getEncoder().encodeToString(ivCTAndTag);
    }

    private static byte[] generateRandomIV() {
        byte[] iv = new byte[GCM_IV_SIZE_BYTES];
        SecureRandom random = new SecureRandom();
        random.nextBytes(iv);
        return iv;
    }

    public static String decrypt(String encryptedPassword, SecretKey key) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

        byte[] ivAndCTWithTag = Base64.getDecoder().decode(encryptedPassword);

        GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_SIZE_BITS, ivAndCTWithTag, 0, GCM_IV_SIZE_BYTES);
        cipher.init(Cipher.DECRYPT_MODE, key, spec);

        byte[] plaintext = cipher.doFinal(ivAndCTWithTag, GCM_IV_SIZE_BYTES, ivAndCTWithTag.length - GCM_IV_SIZE_BYTES);

        return new String(plaintext, UTF_8);
    }

    public static void main(String[] args) throws Exception {
        PasswordVault vault = new PasswordVault();
        PasswordEntry passwordEntry = readPlainPasswordEntry();
        vault.encryptAndStorePasswordEntry(passwordEntry);
        System.out.println(vault.vaultBoxes);
        PasswordEntry decryptedPasswordEntry = vault.retrieveAndDecryptPasswordEntry();
        System.out.println(decryptedPasswordEntry);
    }

    public static PasswordEntry readPlainPasswordEntry() {
        try (Scanner keyboard = new Scanner(System.in)) {
            System.out.println("Please enter in the website that you would like to store a password:");
            String website = keyboard.nextLine();
            System.out.println("Please enter your username");
            String login = keyboard.nextLine();
            System.out.println("Please enter your password");
            String password = keyboard.nextLine();

            return new PasswordEntry(website, login, password);
        }
    }
}
导入静态java.nio.charset.StandardCharsets.UTF_8;
导入java.security.GeneralSecurityException;
导入java.security.NoSuchAlgorithmException;
导入java.security.SecureRandom;
导入java.util.ArrayList;
导入java.util.Base64;
导入java.util.Scanner;
导入javax.crypto.Cipher;
导入javax.crypto.KeyGenerator;
导入javax.crypto.SecretKey;
导入javax.crypto.spec.gcmpareterspec;
公共类密码库{
私有静态最终整型密钥\u大小\u位=128;
专用静态最终整数GCM_标记_大小_位=128;
专用静态最终整数GCM_IV_大小_字节=12;
私人ArrayList保险箱;
私钥;
public PasswordVault()引发NoSuchAlgorithmException{
vaultBoxes=newarraylist();
key=generateKey();
}
public void encryptAndStorePasswordEntry(PasswordEntry PasswordEntry)引发GeneralSecurityException{
String encryptedPassword=encrypt(passwordEntry.getPassword(),key);
PasswordEntry savePass=新的PasswordEntry(PasswordEntry.getWebsite(),PasswordEntry.getLogin(),
加密密码);
vaultbox.add(savePass);
}
public PasswordEntry Retrieve和DecryptPasswordEntry()引发GeneralSecurityException{
//要想办法检索特定条目的密码吗
PasswordEntry encryptedPasswordEntry=vaultbox.get(0);
字符串密码=解密(encryptedPasswordEntry.getP
import static java.nio.charset.StandardCharsets.UTF_8;

import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Scanner;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;

public class PasswordVault {
    private static final int KEY_SIZE_BITS = 128;
    private static final int GCM_TAG_SIZE_BITS = 128;
    private static final int GCM_IV_SIZE_BYTES = 12;
    private ArrayList<PasswordEntry> vaultBoxes;
    private SecretKey key;

    public PasswordVault() throws NoSuchAlgorithmException {
        vaultBoxes = new ArrayList<>();
        key = generateKey();
    }

    public void encryptAndStorePasswordEntry(PasswordEntry passwordEntry) throws GeneralSecurityException {
        String encryptedPassword = encrypt(passwordEntry.getPassword(), key);
        PasswordEntry savePass = new PasswordEntry(passwordEntry.getWebsite(), passwordEntry.getLogin(),
                encryptedPassword);
        vaultBoxes.add(savePass);
    }

    public PasswordEntry retrieveAndDecryptPasswordEntry() throws GeneralSecurityException {
        // TODO think of a way to retrieve the password for a specific entry
        PasswordEntry encryptedPasswordEntry = vaultBoxes.get(0);
        String password = decrypt(encryptedPasswordEntry.getPassword(), key);
        return new PasswordEntry(encryptedPasswordEntry.getWebsite(), encryptedPasswordEntry.getLogin(), password);
    }

    public static SecretKey generateKey() throws NoSuchAlgorithmException {
        SecureRandom random = SecureRandom.getInstanceStrong();
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(KEY_SIZE_BITS, random);
        return keyGen.generateKey();
    }

    public static String encrypt(String password, SecretKey key) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

        byte[] iv = generateRandomIV();

        GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, spec);

        byte[] bytePassword = password.getBytes(UTF_8);
        byte[] ivCTAndTag = new byte[GCM_IV_SIZE_BYTES + cipher.getOutputSize(bytePassword.length)];
        System.arraycopy(iv, 0, ivCTAndTag, 0, GCM_IV_SIZE_BYTES);

        cipher.doFinal(bytePassword, 0, bytePassword.length, ivCTAndTag, GCM_IV_SIZE_BYTES);

        return Base64.getEncoder().encodeToString(ivCTAndTag);
    }

    private static byte[] generateRandomIV() {
        byte[] iv = new byte[GCM_IV_SIZE_BYTES];
        SecureRandom random = new SecureRandom();
        random.nextBytes(iv);
        return iv;
    }

    public static String decrypt(String encryptedPassword, SecretKey key) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

        byte[] ivAndCTWithTag = Base64.getDecoder().decode(encryptedPassword);

        GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_SIZE_BITS, ivAndCTWithTag, 0, GCM_IV_SIZE_BYTES);
        cipher.init(Cipher.DECRYPT_MODE, key, spec);

        byte[] plaintext = cipher.doFinal(ivAndCTWithTag, GCM_IV_SIZE_BYTES, ivAndCTWithTag.length - GCM_IV_SIZE_BYTES);

        return new String(plaintext, UTF_8);
    }

    public static void main(String[] args) throws Exception {
        PasswordVault vault = new PasswordVault();
        PasswordEntry passwordEntry = readPlainPasswordEntry();
        vault.encryptAndStorePasswordEntry(passwordEntry);
        System.out.println(vault.vaultBoxes);
        PasswordEntry decryptedPasswordEntry = vault.retrieveAndDecryptPasswordEntry();
        System.out.println(decryptedPasswordEntry);
    }

    public static PasswordEntry readPlainPasswordEntry() {
        try (Scanner keyboard = new Scanner(System.in)) {
            System.out.println("Please enter in the website that you would like to store a password:");
            String website = keyboard.nextLine();
            System.out.println("Please enter your username");
            String login = keyboard.nextLine();
            System.out.println("Please enter your password");
            String password = keyboard.nextLine();

            return new PasswordEntry(website, login, password);
        }
    }
}