Good evening,
I'm developping an application to encrypt data with tripleDES before getting inserted in oracle database.
Another application must consult the database, decrypt the data then show it in a jtable.
I'm a biginner in the security field, i found a source implementing triple DES encryption.
1-some byte from the encrypted data like the cote(') make some problem when executing the query, i'd like to change the type of the encryption bytes, i heard about UTF8 but i don't know how to use it.
2-when I decrypt the data from the resultset and put it in the jtable the first culumn is empty and I receive this error:
"javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher. "
It can't decrypt the first object of the resultset cause of the missing byte.
Here is the code:
The encryption class:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
public class TripleDES {
public File f = new File("clef");
/** Read a TripleDES secret key from the specified file */
public SecretKey readKey(File f)
throws IOException, NoSuchAlgorithmException,
InvalidKeyException, InvalidKeySpecException
{
// Read the raw bytes from the keyfile
DataInputStream in = new DataInputStream(new FileInputStream(f));
byte[] rawkey = new byte[(int)f.length()];
in.readFully(rawkey);
in.close();
// Convert the raw bytes to a secret key like this
DESedeKeySpec keyspec = new DESedeKeySpec(rawkey);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
SecretKey key = keyfactory.generateSecret(keyspec);
return key;
}
public void encrypt(SecretKey key, InputStream in, OutputStream out)
throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, IOException
{
// Create and initialize the encryption engine
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, key);
// Create a special output stream to do the work for us
CipherOutputStream cos = new CipherOutputStream(out, cipher);
// Read from the input and write to the encrypting output stream
byte[] buffer = new byte[2048];
int bytesRead;
while((bytesRead = in.read(buffer)) != -1) {
cos.write(buffer, 0, bytesRead);
}
cos.close();
// For extra security, don't leave any plaintext hanging around memory.
java.util.Arrays.fill(buffer, (byte) 0);
}
public void decrypt(SecretKey key, InputStream in, OutputStream out)
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
IllegalBlockSizeException, NoSuchPaddingException,
BadPaddingException
{
// Create and initialize the decryption engine
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, key);
// Read bytes, decrypt, and write them out.
byte[] buffer = new byte[2048];
int bytesRead;
while((bytesRead = in.read(buffer)) != -1) {
out.write(cipher.update(buffer, 0, bytesRead));
}
// Write out the final bunch of decrypted bytes
out.write(cipher.doFinal());
out.flush();
}
//manipulate a
string and not streams when enrypting
public String crypterString(String s){
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
try {
encrypt(readKey(f), in, out);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return out.toString();
}
//manipulate a string and not streams when decrypting
public String decrypterString(String s){
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
try {
decrypt(readKey(f), in, out);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return out.toString();
}
}
I insert encrypt the data with the void crypterString() then i insert it in the database.
And here is the vector i use to fill in the jtable(the decryption application side)
public Vector donnee(ResultSet rs)
{int numRows=0;
int numColumns = 0;
TripleDES td = new TripleDES();
try {
td.readKey(td.f);
} catch (InvalidKeyException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InvalidKeySpecException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Vector data = new Vector();
try{
numColumns=rs.getMetaData().getColumnCount();
while (rs.next())
{ Vector rowData = new Vector();
for (int i = 0; i < numColumns; i++)
rowData.addElement(td.decrypterString(rs.getObject(i+1).toString()));
data.addElement(rowData);
numRows++;
}
}
catch (java.sql.SQLException e)
{
JOptionPane.showMessageDialog(null,"Erreur de connexion � la base. Veuillez contacter votre administrateur syst�me","Connexion",JOptionPane.WARNING_MESSAGE);
}return data;
}
Thanks for your help.