IllegalBlockSizeException Problem
I am working on a school project and am having a bit of a problem with the two following functions. If I use the ImportArray function it will throw an IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher. As far as I could tell that was because the byte arrays I was creating on the import from the input strings after they were split up were not the same as before. Perhaps I am viewing this all wrong. Any chance you could tell me where I have made a mistake here?
Code Java:
public void ImportArray() throws Exception
{
FileReader inputFile = new FileReader("students.txt");
Scanner scannedFile = new Scanner(inputFile);
String buffer = null;
String[] splitter;
while (scannedFile.hasNext())
{
if(buffer == null)
{
buffer = scannedFile.next();
}
else
{
buffer = buffer + scannedFile.next();
}
}
scannedFile.close();
splitter = buffer.split(delimiter);
for (int i = 0; i < splitter.length; i++)
{
Student ImportedStudent = new Student();
String stemp1 = splitter[i];
byte[] temp1 = stemp1.getBytes();
byte[] temp2 = splitter[i+1].getBytes();
byte[] temp3 = splitter[i+2].getBytes();
byte[] temp4 = splitter[i+3].getBytes();
byte[] temp5 = splitter[i+4].getBytes();
String STemp1 = EMan.DecodeDataString(temp1);
String STemp2 = EMan.DecodeDataString(temp2);
String STemp3 = EMan.DecodeDataString(temp3);
String STemp4 = EMan.DecodeDataString(temp4);
String STemp5 = EMan.DecodeDataString(temp5);
ImportedStudent.FirstName = STemp1;
ImportedStudent.LastName = STemp2;
ImportedStudent.CurrentTest = STemp3;
ImportedStudent.CurrentGrade = Double.valueOf(STemp4);
ImportedStudent.TestCompleted = Boolean.valueOf(STemp5);
push(ImportedStudent);
i = i + 4;
}
}
public void ExportArray() throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException
{
FileWriter outputFile = new FileWriter ("students.txt", false);
String encryptedStudent = "";
for (int i = 0; i < StudentArray.length; i++)
{
Student ExportStudent = StudentArray[i];
if(ExportStudent != null)
{
byte[] temp1 = EMan.EncodeDataString(ExportStudent.FirstName);
byte[] temp2 = EMan.EncodeDataString(ExportStudent.LastName);
byte[] temp3 = EMan.EncodeDataString(ExportStudent.CurrentTest);
String STemp1 = String.valueOf(ExportStudent.CurrentGrade);
byte[] temp4 = EMan.EncodeDataString(STemp1);
String STemp2 = String.valueOf(ExportStudent.TestCompleted);
byte[] temp5 = EMan.EncodeDataString(STemp2);
if(i > 0)
{
encryptedStudent = delimiter + temp1 + delimiter + temp2 + delimiter + temp3 + delimiter + temp4 + delimiter + temp5;
}
else
{
encryptedStudent = temp1 + delimiter + temp2 + delimiter + temp3 + delimiter + temp4 + delimiter + temp5;
}
outputFile.write(encryptedStudent);
}
}
outputFile.close();
}
Re: IllegalBlockSizeException Problem
I have no idea what you are trying to do, what your problem is or where it is occuring. Any chance you can provide more information?
Re: IllegalBlockSizeException Problem
Your code is using a lot of third party classes. There is no way we can help you use them.
If we were to help, You need to provide us with the import statements you use to compile your program and the API doc for all the third party classes you are using.
Is your code getting the exception when it executes
or is your code supposed to throw the exception when it detects the error?
Re: IllegalBlockSizeException Problem
The program stores student account information which would include first name, last name, what the name of the current test is, if the student has completed it, and if they have a grade for the test, what it is. After being encrypted, this information is all exported to a file called students.txt via a string with delimiters. The ImportArray Function is for the Instructor Role to be able to load a class list and view the information. It will have to be seperated back up into the byte arrays and decrypted. That is where the problem is.
Re: IllegalBlockSizeException Problem
I would move that there is something seriously wrong with you code if it is throwing all those exceptions that you have to handle. You should figure out what is throwing the exceptions and fix each one - one at a time.
Please post complete code and copy and paste the errors from the console so that we may further help you.
Re: IllegalBlockSizeException Problem
The complete code for this class:
Code Java:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
public class StudentManager
{
private static TestManager TMan;
private static EncryptionManager EMan;
protected final int DEFCAP = 50; //Maximum of number of Students per class
protected Student[] StudentArray; //Student Array
protected int topIndex = -1; // index of top element in stack
private boolean classLoaded;
private String delimiter = "-";
private class Student extends Object
{
String FirstName = "John";
String LastName = "Doe";
String CurrentTest = "none";
double CurrentGrade = 0.0;
boolean TestCompleted = false;
}
public StudentManager(TestManager man)
{
TMan = man; //The Test manager
Student CurrentStudent = null; //For purpose of tracking logged in student performance
StudentArray = new Student[50]; //Maximum of 50 Students per class
classLoaded = false;
}
public void initialize() throws Exception
{
EMan = new EncryptionManager(TMan);
EMan.initialize();
testSystem();
}
public void ImportArray() throws Exception
{
FileReader inputFile = new FileReader("students.txt");
Scanner scannedFile = new Scanner(inputFile);
String buffer = null;
String[] splitter;
while (scannedFile.hasNext())
{
if(buffer == null)
{
buffer = scannedFile.next();
}
else
{
buffer = buffer + scannedFile.next();
}
}
scannedFile.close();
splitter = buffer.split(delimiter);
for (int i = 0; i < splitter.length; i++)
{
Student ImportedStudent = new Student();
String stemp1 = splitter[i];
byte[] temp1 = stemp1.getBytes();
byte[] temp2 = splitter[i+1].getBytes();
byte[] temp3 = splitter[i+2].getBytes();
byte[] temp4 = splitter[i+3].getBytes();
byte[] temp5 = splitter[i+4].getBytes();
String STemp1 = EMan.DecodeDataString(temp1);
String STemp2 = EMan.DecodeDataString(temp2);
String STemp3 = EMan.DecodeDataString(temp3);
String STemp4 = EMan.DecodeDataString(temp4);
String STemp5 = EMan.DecodeDataString(temp5);
ImportedStudent.FirstName = STemp1;
ImportedStudent.LastName = STemp2;
ImportedStudent.CurrentTest = STemp3;
ImportedStudent.CurrentGrade = Double.valueOf(STemp4);
ImportedStudent.TestCompleted = Boolean.valueOf(STemp5);
push(ImportedStudent);
i = i + 4;
}
}
public void ExportArray() throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException
{
FileWriter outputFile = new FileWriter ("students.txt", false);
String encryptedStudent = "";
for (int i = 0; i < StudentArray.length; i++)
{
Student ExportStudent = StudentArray[i];
if(ExportStudent != null)
{
byte[] temp1 = EMan.EncodeDataString(ExportStudent.FirstName);
byte[] temp2 = EMan.EncodeDataString(ExportStudent.LastName);
byte[] temp3 = EMan.EncodeDataString(ExportStudent.CurrentTest);
String STemp1 = String.valueOf(ExportStudent.CurrentGrade);
byte[] temp4 = EMan.EncodeDataString(STemp1);
String STemp2 = String.valueOf(ExportStudent.TestCompleted);
byte[] temp5 = EMan.EncodeDataString(STemp2);
if(i > 0)
{
encryptedStudent = delimiter + temp1 + delimiter + temp2 + delimiter + temp3 + delimiter + temp4 + delimiter + temp5;
}
else
{
encryptedStudent = temp1 + delimiter + temp2 + delimiter + temp3 + delimiter + temp4 + delimiter + temp5;
}
outputFile.write(encryptedStudent);
}
}
outputFile.close();
}
public void testSystem() throws Exception
{
Student NewStudent1 = new Student();
NewStudent1.FirstName = "Nelson";
NewStudent1.LastName = "Jones";
NewStudent1.CurrentTest = "Summer2011";
NewStudent1.CurrentGrade = 0.0;
NewStudent1.TestCompleted = false;
push(NewStudent1);
Student NewStudent2 = new Student();
NewStudent2.FirstName = "Ronald";
NewStudent2.LastName = "Nelson";
NewStudent2.CurrentTest = "Summer2011";
NewStudent2.CurrentGrade = 0.0;
NewStudent2.TestCompleted = false;
push(NewStudent2);
Student NewStudent3 = new Student();
NewStudent3.FirstName = "Jacqueline";
NewStudent3.LastName = "Ahner";
NewStudent3.CurrentTest = "Summer2011";
NewStudent3.CurrentGrade = 0.0;
NewStudent3.TestCompleted = false;
push(NewStudent3);
ExportArray();
ImportArray();
}
public boolean IsInClass()
{
if(classLoaded == false)
{
return false;
}
return false;
}
private class StudentArrayException extends RuntimeException
{
public StudentArrayException(String message)
{
super(message);
}
}
public void push(Student studentAdd)
{
if (!isFull())
{
topIndex++;
StudentArray[topIndex] = studentAdd;
}
else
throw new StudentArrayException("Push attempted on a full stack.");
}
public void pop()
{
if (!isEmpty())
{
StudentArray[topIndex] = null;
topIndex--;
}
else
throw new StudentArrayException("Pop attempted on an empty stack.");
}
public Object top()
{
Object topOfStack = null;
if (!isEmpty())
topOfStack = StudentArray[topIndex];
else
throw new StudentArrayException("Top attempted on an empty stack.");
return topOfStack;
}
public boolean isEmpty()
{
if (topIndex == -1)
return true;
else
return false;
}
public boolean isFull()
{
if (topIndex == (DEFCAP - 1))
return true;
else
return false;
}
}
Re: IllegalBlockSizeException Problem
The complete code for the encryption class:
Code Java:
import javax.crypto.Cipher;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.InvalidKeyException;
import java.security.SecureRandom;
public class EncryptionManager
{
private static TestManager TMan;
private static Key key;
private static Cipher cipher;
public EncryptionManager(TestManager man)
{
TMan = man; //The Test manager
key = null;
cipher = null;
}
public byte[] EncodeDataString(String importData) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException
{
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] exportData = importData.getBytes("UTF8");
return cipher.doFinal(exportData);
}
public String DecodeDataString(byte[] importData) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException
{
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] recoveredBytes = cipher.doFinal(importData);
String exportData = new String(recoveredBytes, "UTF8");
return exportData;
}
public void initialize() throws Exception
{
KeyGenerator generator;
generator = KeyGenerator.getInstance("DES");
generator.init(new SecureRandom());
key = generator.generateKey();
cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
}
}
Re: IllegalBlockSizeException Problem
Please copy and paste here the full text of your error messages.
To copy the contents of the command prompt window:
Click on Icon in upper left corner
Select Edit
Select 'Select All' - The selection will show
Click in upper left again
Select Edit and click 'Copy'
Paste here.
Re: IllegalBlockSizeException Problem
Everything from the Console"
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherC ore.java:750)
at com.sun.crypto.provider.CipherCore.doFinal(CipherC ore.java:676)
at com.sun.crypto.provider.DESCipher.engineDoFinal(DE SCipher.java:314)
at javax.crypto.Cipher.doFinal(Cipher.java:2086)
at EncryptionManager.DecodeDataString(EncryptionManag er.java:35)
at StudentManager.ImportArray(StudentManager.java:94)
at StudentManager.testSystem(StudentManager.java:178)
at StudentManager.initialize(StudentManager.java:57)
at TestManager.InitializeCore(TestManager.java:45)
at TestManager.main(TestManager.java:31)
Re: IllegalBlockSizeException Problem
Isn't the exception obvious? Your input must have a length which is a multiple of 8. The input you are passing in is not a multiple of 8. So find out why and rectify that.
Re: IllegalBlockSizeException Problem
Quote:
IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
What is the length of the byte array that is passed to the doFinal method()?
Why isn't it a multiple of 8?
Re: IllegalBlockSizeException Problem
I understood that. However, I don't see what it would no longer have a length of 8. It had one before it was exported.
Re: IllegalBlockSizeException Problem
It's not a multiple of 8 because you only initalized the array of students. It is an empty array. It needs to be filled with data. Your export from the file is not going where it should.
Re: IllegalBlockSizeException Problem
Actually it is Spidey because I did it with the testSystem function I threw in there. There are three students added.
Re: IllegalBlockSizeException Problem
all I can tell you with the length is that if I do a System.err.print for byte[] temp1 in each of the functions, the ExportArray lenght comes up as 8816 and the ImportArray function has 111111. No earthly idea why.
Re: IllegalBlockSizeException Problem
Quote:
Originally Posted by
GeekWarth
I don't see what it would no longer have a length of 8.
That is the crux of the problem. You need to debug your code and find out why the length is not a multiple of 8. Place a bunch of print statements throughout your code to find out exactly what data is being used.
Re: IllegalBlockSizeException Problem
Junky, I spent most of my day doing that very thing. All I know is that if System.err.print for byte[] temp1 throughout byte[] temp5 in the ExportArray function, they will look exactly the same to the strings splitter[i] through splitter[i+4] in the ImportArray function. As soon as you try to convert those strings over to byte arrays, it all falls apart.
Re: IllegalBlockSizeException Problem
Don't you think that splitter gets different bytes each time???
Try writing System.err.print under each line where you assigning splitter to byte and find the size of array. I guess if splitter is not getting multiple of 8.
Re: IllegalBlockSizeException Problem
OK since I am only making changes at this point to Import and Export Array functions so far, I am only including those. I changed things again, but to greatly simplify and remove the process of delimiting the byte arrays and strings before they were encoded. It is much cleaner this way, and should have actually worked, but I am still having the same problems.
Code Java:
public void ImportArray() throws Exception
{
File file = new File("students.dat");
FileInputStream inputFile = new FileInputStream(file);
Scanner scannedFile = new Scanner(inputFile);
int length = (int)file.length();
byte[] input = new byte[length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < input.length && (numRead=inputFile.read(input, offset, input.length-offset)) >= 0)
{
offset += numRead;
}
System.err.println(input);
String bigBuffer = EMan.DecodeDataString(input);
String[] splitter;
splitter = bigBuffer.split(delimiter);
System.err.println(bigBuffer);
for (int i = 0; i < splitter.length; i++)
{
Student ImportedStudent = new Student();
System.err.println(splitter[i]);
/*
ImportedStudent.FirstName = splitter[i];
ImportedStudent.LastName = splitter[i+1];
ImportedStudent.CurrentTest = splitter[i+2];
ImportedStudent.CurrentGrade = Double.valueOf(splitter[i+3]);
ImportedStudent.TestCompleted = Boolean.valueOf(splitter[i+4]);
push(ImportedStudent);
*/
i = i + 4;
}
}
public void ExportArray() throws Exception
{
FileOutputStream outputFile = new FileOutputStream ("students.datt", false);
String encryptedStudent = "";
for (int i = 0; i < StudentArray.length; i++)
{
Student ExportStudent = StudentArray[i];
if(ExportStudent != null)
{
String STemp1 = String.valueOf(ExportStudent.CurrentGrade);
String STemp2 = String.valueOf(ExportStudent.TestCompleted);
if(i > 0)
{
encryptedStudent = encryptedStudent + delimiter + ExportStudent.FirstName + delimiter + ExportStudent.LastName + delimiter + ExportStudent.CurrentTest + delimiter + STemp1 + delimiter + STemp2;
}
else
{
encryptedStudent = ExportStudent.FirstName + delimiter + ExportStudent.LastName + delimiter + ExportStudent.CurrentTest + delimiter + STemp1 + delimiter + STemp2;
}
}
}
byte[] output = EMan.EncodeDataString(encryptedStudent);
System.err.println(output);
outputFile.write(output);
outputFile.close();
}
here is the console output:
[B@31fa7bbf
[B@1ea40b04
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherC ore.java:750)
at com.sun.crypto.provider.CipherCore.doFinal(CipherC ore.java:676)
at com.sun.crypto.provider.DESCipher.engineDoFinal(DE SCipher.java:314)
at javax.crypto.Cipher.doFinal(Cipher.java:2086)
at EncryptionManager.DecodeDataString(EncryptionManag er.java:37)
at StudentManager.ImportArray(StudentManager.java:82)
at StudentManager.testSystem(StudentManager.java:166)
at StudentManager.initialize(StudentManager.java:61)
at TestManager.InitializeCore(TestManager.java:45)
at TestManager.main(TestManager.java:31)
Right now I am just trying to find away to directly create a byte array from the stream that works. Apparently this does not.
Re: IllegalBlockSizeException Problem
Quote:
trying to find away to directly create a byte array from the stream that works.
Can you post a small program that does only that to work on to solve that problem without the rest of the code?
You should change your debug printouts. These don't give any useful information:
[B@31fa7bbf
[B@1ea40b04
Use Arrays toString() to show the contents of the array
or print the array's length
Re: IllegalBlockSizeException Problem
Umm...actually I beleive the programming gods were seriously screwwing with me last night. Because I woke this morning, cleaned out a few little pieces of unused extra and this works now. Go figure.
Re: IllegalBlockSizeException Problem
@GeekWarth: Try to print the value of offset, if it's -1, then in the loop set condition as offset!=-1
Try this and share here.
Also, try to write a test program that compose of 5 to 10 lines so that everyone could help you and you could use that in your main program.