javax.crypto.BadPaddingException:给定最终块在解密文件时未正确填充

时间:2017-11-05 22:17:20

标签: java encryption des

我正在编写一个小型安全存储服务器模拟,以便通过加密技术和算法获得家庭。我坚持解密文件内容。项目有点大,可以放在这里,所以我会从代码中添加例外(我使用的方法和出现问题的地方)。 问题是,当我尝试解密文件时,会发生BadPaddingException。 Crypto类的例外,其中实现了主密码逻辑

notification.fireDate

当我尝试使用对称文件enc和dec之后,像:

public class Crypto {

private Cipher asymmCipher;
//one cipher for asymmetric and one for symmetric
private Cipher symmCipher;

public IvParameterSpec iv;
SecureRandom sr;
KeyGenerator kg;

   public Crypto() throws NoSuchAlgorithmException, NoSuchPaddingException {
      this.asymmCipher = Cipher.getInstance("RSA");
      this.symmCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
   }
 /*
        Method for symmetric encription of file
 */
  public byte[] SymmetricFileEncryption(byte[] file, SecretKey key)
          throws InvalidKeyException, IllegalBlockSizeException,
          BadPaddingException, NoSuchAlgorithmException {

      this.symmCipher.init(Cipher.ENCRYPT_MODE, key);

      return this.symmCipher.doFinal(file);
  }

 /*
        Method for symmetric decription of file
 */
  public byte[] SymmetricFileDecription(byte[] file, SecretKey key)
          throws InvalidKeyException, IllegalBlockSizeException,
          BadPaddingException, InvalidAlgorithmParameterException {
      this.symmCipher.init(Cipher.DECRYPT_MODE, key);
      return this.symmCipher.doFinal(file);
  }
    /*
        Method for write encrypted file
 */
public void writeToFile(File output, byte[] data, SecretKey key)
        throws IllegalBlockSizeException, BadPaddingException, 
        IOException, InvalidKeyException, NoSuchAlgorithmException {

    FileOutputStream fos = new FileOutputStream(output);
    byte[] encContent = SymmetricFileEncryption(data, key);
    fos.write(encContent);
    fos.flush();
    fos.close();
}
   public byte[] readFromFile(File input, SecretKey key)
        throws IllegalBlockSizeException, BadPaddingException, 
        IOException, InvalidKeyException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {

    byte[] fileContent = new byte[(int) input.length()];
    FileInputStream fis = new FileInputStream(input);
    fis.read(fileContent);
    fis.close();

    return SymmetricFileDecription(fileContent, key);
}

}

效果很好。

除了用于创建新文件的服务器和用于编辑文件(我需要阅读和解密)的服务器

                    String test = "Test symmetric file enc / dec";
                    byte[] tesT = aCrypto.SymmetricFileEncryption(test.getBytes(), sessionKey);
                    System.out.println("ENC FROM SERVER " + new String(tesT));
                    String test2 = new String(aCrypto.SymmetricFileDecription(tesT, sessionKey));
                    System.out.println("DEC FROM SERVER: " + test2);

另一个例子 - 我将print放在writeToFile方法中并测试了write和read:

               if ("new".equals(option)) {
                    String fileName = aCrypto.DecryptStringSymmetric((String) ois.readObject(), sessionKey);
                    System.out.println("FILE NAME SERVER POSLAN IS UPANEL CONTROLLERA : " + fileName);
                    // String cFileName = aCrypto.EncryptStringSymmetric(fileName, sessionKey);
                    String formatedEncFileName = aCrypto.encodeWithSHA256(fileName).replaceAll("\\/", "");
                    File f = new File("src/server/users/" + userName + "/" + formatedEncFileName);

                    if (!f.exists()) {
                        f.createNewFile();
                        System.out.println("FILE CREATED!");
                        fileNamesMap.put(formatedEncFileName, fileName);
                        serialize(fileNamesMap);
                        System.out.println("MAP VALUE FOR " + fileNamesMap.get(formatedEncFileName));
                    }
                    byte[] file = aCrypto.SymmetricFileDecription(((byte[]) ois.readObject()), sessionKey);
                    System.out.println("FILE CONTENT :  " + new String(file));
                   // String encContent = aCrypto.EncryptStringSymmetric(new String(file), sessionKey);
                    aCrypto.writeToFile(f, file, sessionKey);
                    oos.writeObject(aCrypto.EncryptStringSymmetric(((f.exists()) ? "true" : "false"), sessionKey));
                    changeFileWatcher(userName);
                }
                    if (("edit").equals(option)) {
                    fileName = aCrypto.DecryptStringSymmetric((String) ois.readObject(), sessionKey);
                    byte[] content = aCrypto.readFromFile(new File(PATH + userName + "/" + (String)  getKeyFromValue(fileNamesMap, fileName.split("/")[4])), sessionKey); //Exception in readFromFile
                    String fileContent = aCrypto.DecryptStringSymmetric(new String(content), sessionKey);
                    oos.writeObject(aCrypto.EncryptStringSymmetric(fileContent, sessionKey));
                    System.out.println("NAME FROM SERVER IN EDIT : " + fileName);
                }
                if (("modify").equals(option)) {
                    String editedFileContent = aCrypto.DecryptStringSymmetric((String) ois.readObject(), sessionKey);
                    System.out.println("NAME FROM SERVER IN MODIFY: " + fileName);
                    String encrytedFileContent = aCrypto.EncryptStringSymmetric(editedFileContent, sessionKey);
                    File f = new File(PATH + userName + "/" + (String) getKeyFromValue(fileNamesMap, fileName.split("/")[4]));
                    aCrypto.writeToFile(f, encrytedFileContent.getBytes(), sessionKey);
                    oos.writeObject(aCrypto.EncryptStringSymmetric("true", sessionKey));
                }

输出:

    String test = "Test symmetric file enc / dec";
    File fileTest = new File("src/server/testFileEnc");
    if(!fileTest.exists()) {
        fileTest.createNewFile();
    }
    aCrypto.writeToFile(fileTest, test.getBytes(), sessionKey);
                    String decryptedFromFile = new String(aCrypto.readFromFile(fileTest , sessionKey));
    System.out.println("DECRYPTED DATA " + decryptedFromFile);

1 个答案:

答案 0 :(得分:0)

最后我发现了问题。问题是我有点傻:) 我忘记了每个新客户端都会生成新的会话密钥,所以即使我创建了特定用户的加密文件,在应用程序重启后,也会向用户提供新的3DES密钥,并且使用该新密钥我试图解密加密的文件不同的3DES键。 我需要在服务器上存储会话密钥,并为特定用户使用相同的密钥