Hi i hav such code that encrypt and decrypt file in DES algorithm .
i want to change my code to be triple DES encryption / decryption .
my code is below :
First, my methods are :
public class DESEncrypt
{
public static void encrypt(String key, InputStream is, OutputStream os) throws Exception {
encryptOrDecrypt(key, Cipher.ENCRYPT_MODE, is, os);
}
public static void decrypt(String key, InputStream is, OutputStream os) throws Exception {
encryptOrDecrypt(key, Cipher.DECRYPT_MODE, is, os);
}
public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Exception {
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey desKey = skf.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES");
if (mode == Cipher.ENCRYPT_MODE) {
cipher.init(Cipher.ENCRYPT_MODE, desKey);
CipherInputStream cis = new CipherInputStream(is, cipher);
makeFile(cis, os);
} else if (mode == Cipher.DECRYPT_MODE) {
cipher.init(Cipher.DECRYPT_MODE, desKey);
CipherOutputStream cos = new CipherOutputStream(os, cipher);
makeFile(is, cos);
}
}
public static void makeFile(InputStream is, OutputStream os) throws IOException {
byte[] bytes = new byte[64];
int numBytes;
while ((numBytes = is.read(bytes)) != -1) {
os.write(bytes, 0, numBytes);
}
os.flush();
os.close();
is.close();
}
}
public class EncryptTXT extends javax.swing.JFrame {
String key="Java#123##"; //This is the Key for Encryption
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try{
JFileChooser fc=new JFileChooser();
fc.showOpenDialog(null);
String path=fc.getSelectedFile().getAbsolutePath();
jLabel2.setText(path);
File f=fc.getSelectedFile();
FileInputStream fis=new FileInputStream(f);
FileOutputStream fos=new FileOutputStream("C:/Users/user/Desktop/encrypted.txt");
Thread.sleep(2000);
DESEncrypt.encrypt(key, fis, fos);
jLabel4.setText("C:/Users/user/Desktop/encrypted.txt");
The 3DES keys should be 16 or 24 bytes long, not 8.
Change "DES" to "DESede" as Maarten Bodewes suggested or "DESede\ECB\NoPadding" (in .getInstance() method)
Related
I'm trying to transfer an AES encrypted file through socket programming, but when I specify the file path it gives the following exception, and when I try to transfer an unencrypted file, it works fine.
java.io.FileNotFoundException: salt.ecn (The system cannot find the file specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at nigam.Front.server(Front.java:52)
at nigam.Front$7.run(Front.java:621)
Code:
public class SocketFileExample {
static void server() throws IOException {
ServerSocket ss = new ServerSocket(3434);
Socket socket = ss.accept();
InputStream in = new FileInputStream("salt.ecn");
OutputStream out = socket.getOutputStream();
copy(in, out);
out.close();
in.close();
}
static void client() throws IOException {
Socket socket = new Socket("localhost", 3434);
InputStream in = socket.getInputStream();
OutputStream out = new FileOutputStream("C:\\Users\\SIDDHARTH\\Documents\\NetBeansProjects\\Nigam\\salt.ecn");
copy(in, out);
out.close();
in.close();
}
static void copy(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[8192];
int len = 0;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
}
public static void main(String[] args) throws IOException {
new Thread() {
public void run() {
try {
server();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
client();
}
}
'Code: Encryption code used'
Code: Encryption code used
public class AESFileEncryption {
public static void main(String[] args) throws Exception {
// file to be encrypted
FileInputStream inFile = new FileInputStream("plainfile.txt");
// encrypted file
FileOutputStream outFile = new FileOutputStream("encryptedfile.des");
// password to encrypt the file
String password = "javapapers";
// password, iv and salt should be transferred to the other end
// in a secure manner
// salt is used for encoding
// writing it to a file
// salt should be transferred to the recipient securely
// for decryption
byte[] salt = new byte[8];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(salt);
FileOutputStream saltOutFile = new FileOutputStream("salt.enc");
saltOutFile.write(salt);
saltOutFile.close();
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536,
256);
SecretKey secretKey = factory.generateSecret(keySpec);
SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
//
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
// iv adds randomness to the text and just makes the mechanism more
// secure
// used while initializing the cipher
// file to store the iv
FileOutputStream ivOutFile = new FileOutputStream("iv.enc");
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
ivOutFile.write(iv);
ivOutFile.close();
//file encryption
byte[] input = new byte[64];
int bytesRead;
while ((bytesRead = inFile.read(input)) != -1) {
byte[] output = cipher.update(input, 0, bytesRead);
if (output != null)
outFile.write(output);
}
byte[] output = cipher.doFinal();
if (output != null)
outFile.write(output);
inFile.close();
outFile.flush();
outFile.close();
System.out.println("File Encrypted.");
}
}
Ok guys ! There is my trouble.
I want to read data from an encrypted file and store the decrypted data in a local variable (without save it in a file).
So, when I do the operations (in the same Class) cryptingFile -> DecryptFile -> Storage : It's OK.
But, when I try to run again the code using the crypted file directly, I've got the error "BadPaddingException".
I've no idea what's going on....
Below, the working code:
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
generateKey(clef);
CryptingWithSave(Cipher.ENCRYPT_MODE,"db/db.csv",publicKey,"db/db.csv_encrypted");
decrypt_file("db/db.csv_encrypted",publicKey);
System.out.println(tab);
}
public static void generateKey (String clef) throws NoSuchAlgorithmException{
final KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
final SecretKey key = keyGen.generateKey();
publicKey= new SecretKeySpec(key.getEncoded(),"AES");
}
public static void CryptingWithSave (int Crypting_METHOD,String inputFile, SecretKeySpec clef, String outputFile) throws NoSuchAlgorithmException, NoSuchPaddingException, BadPaddingException, Exception{
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Crypting_METHOD, clef);
FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile);
byte[] input = new byte[64];
int bytesRead;
while ((bytesRead = fis.read(input)) != -1) {
byte[] output = cipher.update(input, 0, bytesRead);
if (output != null)
fos.write(output);
}
byte[] output = cipher.doFinal();
if (output != null)
fos.write(output);
fis.close();
fos.flush();
fos.close();
}
public static void decrypt_file (String inputFile, SecretKeySpec clef) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException{
Cipher cipher2 = Cipher.getInstance("AES");
cipher2.init(Cipher.DECRYPT_MODE, clef);
FileInputStream fis = new FileInputStream(inputFile);
byte[] input = new byte[64];
int bytesRead;
while ((bytesRead = fis.read(input)) != -1) {
byte[] output = cipher2.update(input, 0, bytesRead);
if (output != null)
tab=tab.concat(new String(output));
}
byte[] output = cipher2.doFinal();
if (output != null)
tab=tab.concat(new String(output));
fis.close();
}
There, the unworking code (the only change is the CryptingWithSave which is commented):
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
generateKey(clef);
//CryptingWithSave(Cipher.ENCRYPT_MODE,"db/db.csv",publicKey,"db/db.csv_encrypted");
decrypt_file("db/db.csv_encrypted",publicKey);
System.out.println(tab);
}
public static void generateKey (String clef) throws NoSuchAlgorithmException{
final KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
final SecretKey key = keyGen.generateKey();
publicKey= new SecretKeySpec(key.getEncoded(),"AES");
}
public static void CryptingWithSave (int Crypting_METHOD,String inputFile, SecretKeySpec clef, String outputFile) throws NoSuchAlgorithmException, NoSuchPaddingException, BadPaddingException, Exception{
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Crypting_METHOD, clef);
FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile);
byte[] input = new byte[64];
int bytesRead;
while ((bytesRead = fis.read(input)) != -1) {
byte[] output = cipher.update(input, 0, bytesRead);
if (output != null)
fos.write(output);
}
byte[] output = cipher.doFinal();
if (output != null)
fos.write(output);
fis.close();
fos.flush();
fos.close();
}
public static void decrypt_file (String inputFile, SecretKeySpec clef) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException{
Cipher cipher2 = Cipher.getInstance("AES");
cipher2.init(Cipher.DECRYPT_MODE, clef);
FileInputStream fis = new FileInputStream(inputFile);
byte[] input = new byte[64];
int bytesRead;
while ((bytesRead = fis.read(input)) != -1) {
byte[] output = cipher2.update(input, 0, bytesRead);
if (output != null)
tab=tab.concat(new String(output));
}
byte[] output = cipher2.doFinal();
if (output != null)
tab=tab.concat(new String(output));
fis.close();
}
It is because the next time you run it, it generates a new key which is different from the previous one. Try to use that old key.
I am working on a Encryption/Decryption program in Java. I am using a key called "secret1234" to encrypt and decrypt a message from a text file. This program uses a string for the key. However, I am interested in using a number (integer) for the key so I can generate random numbers. So, how can this program be modified to allow the key to be an integer and not a string for encrypting and descrypting the message?
This is the program:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class Program {
public static void main(String[] args) {
try {
String key = "secret1234";// This is the key
FileInputStream fis = new FileInputStream("text.txt");//text.txt is a text file with a short message
FileOutputStream fos = new FileOutputStream("encryptedText.txt");
encrypt(key, fis, fos);
FileInputStream fis2 = new FileInputStream("encryptedText.txt");
FileOutputStream fos2 = new FileOutputStream("decryptedText.txt");
decrypt(key, fis2, fos2);
} catch (Throwable e) {
e.printStackTrace();
}
}
public static void encrypt(String key, InputStream is, OutputStream os) throws Throwable {
encryptOrDecrypt(key, Cipher.ENCRYPT_MODE, is, os);
}
public static void decrypt(String key, InputStream is, OutputStream os) throws Throwable {
encryptOrDecrypt(key, Cipher.DECRYPT_MODE, is, os);
}
public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey desKey = skf.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES");
if (mode == Cipher.ENCRYPT_MODE) {
cipher.init(Cipher.ENCRYPT_MODE, desKey);
CipherInputStream cis = new CipherInputStream(is, cipher);
doCopy(cis, os);
} else if (mode == Cipher.DECRYPT_MODE) {
cipher.init(Cipher.DECRYPT_MODE, desKey);
CipherOutputStream cos = new CipherOutputStream(os, cipher);
doCopy(is, cos);
}
}
public static void doCopy(InputStream is, OutputStream os) throws IOException {
byte[] bytes = new byte[64];
int numBytes;
while ((numBytes = is.read(bytes)) != -1) {
os.write(bytes, 0, numBytes);
}
os.flush();
os.close();
is.close();
}
}
Use this in your code to generate the key:
String key = String.valueOf(SecureRandom.getInstance("SHA1PRNG").nextInt());
O want to encrypt and decrypt files using my Java program.
These files are compiled Java .class files, I don't know what I am doing wrong. I am just testing now, but after encrypt and decrypt with the same key. It shows that file is
Exception in thread "AWT-EventQueue-0" java.lang.ClassFormatError: Truncated class file
and that class cannot be loaded.
There is my encrypter/decrypter class code:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class EncTool {
public static void encrypt(String key, String filename) throws Throwable {
InputStream is = new FileInputStream("SomeFile.class");
OutputStream os = new FileOutputStream("SomeFile.class");
encrypt(key, Cipher.ENCRYPT_MODE, is, os);
}
public static void decrypt(String key, String filename) throws Throwable {
InputStream is = new FileInputStream("SomeFile.class");
OutputStream os = new FileOutputStream("SomeFile.class");
decrypt(key, Cipher.DECRYPT_MODE, is, os);
}
public static void encrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey desKey = skf.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE
cipher.init(Cipher.ENCRYPT_MODE, desKey);
CipherInputStream cis = new CipherInputStream(is, cipher);
doCopy(cis, os);
}
public static void decrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey desKey = skf.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE
cipher.init(Cipher.DECRYPT_MODE, desKey);
CipherOutputStream cos = new CipherOutputStream(os, cipher);
doCopy(is, cos);
}
public static void doCopy(InputStream is, OutputStream os) throws IOException {
byte[] bytes = new byte[64];
int numBytes;
while ((numBytes = is.read(bytes)) != -1) {
os.write(bytes, 0, numBytes);
}
os.flush();
os.close();
is.close();
}
}
and for testing im executing it that way:
try {
EncTool.encrypt("somekey123", "SomeFile");
EncTool.decrypt("somekey123", "SomeFile");
} catch (Throwable e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
What am i doing wrong?
Or maybe how should it be done?
EDIT
when my code looks that:
public static void encrypt(String key, String filename) throws Throwable {
InputStream is = new FileInputStream("Somefile.class");
OutputStream os = new FileOutputStream("tempfile.class");
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey desKey = skf.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE
cipher.init(Cipher.ENCRYPT_MODE, desKey);
CipherInputStream cis = new CipherInputStream(is, cipher);
doCopy(cis, os);
File file2 = new File("tempfile.class");
File f = new File("somefile.class");
f.delete();
file2.renameTo(f);
}
Now it works, but these deleting and renaming thing doesn't look elegant, how can I do it more efficient?
You must write the output to a new file instead of overwriting the input while you are reading it. The way your code is written now the results will be undefined.
I'm using CipherInputStream and CipherOutputStream to encrypt files using AES.
encrypt(...) seems to be working fine, but my decrypt(...) function only decrypt the first 16 bytes of my files.
Here is my class :
public class AESFiles {
private byte[] getKeyBytes(final byte[] key) throws Exception {
byte[] keyBytes = new byte[16];
System.arraycopy(key, 0, keyBytes, 0, Math.min(key.length, keyBytes.length));
return keyBytes;
}
public Cipher getCipherEncrypt(final byte[] key) throws Exception {
byte[] keyBytes = getKeyBytes(key);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
return cipher;
}
public Cipher getCipherDecrypt(byte[] key) throws Exception {
byte[] keyBytes = getKeyBytes(key);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
return cipher;
}
public void encrypt(File inputFile, File outputFile, byte[] key) throws Exception {
Cipher cipher = getCipherEncrypt(key);
FileOutputStream fos = null;
CipherOutputStream cos = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(inputFile);
fos = new FileOutputStream(outputFile);
cos = new CipherOutputStream(fos, cipher);
byte[] data = new byte[1024];
int read = fis.read(data);
while (read != -1) {
cos.write(data, 0, read);
read = fis.read(data);
System.out.println(new String(data, "UTF-8").trim());
}
cos.flush();
} finally {
fos.close();
cos.close();
fis.close();
}
}
public void decrypt(File inputFile, File outputFile, byte[] key) throws Exception {
Cipher cipher = getCipherDecrypt(key);
FileOutputStream fos = null;
CipherInputStream cis = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(inputFile);
cis = new CipherInputStream(fis, cipher);
fos = new FileOutputStream(outputFile);
byte[] data = new byte[1024];
int read = cis.read(data);
while (read != -1) {
fos.write(data, 0, read);
read = cis.read(data);
System.out.println(new String(data, "UTF-8").trim());
}
} finally {
fos.close();
cis.close();
fis.close();
}
}
public static void main(String args[]) throws Exception {
byte[] key = "mykey".getBytes("UTF-8");
new AESFiles().encrypt(new File("C:\\Tests\\secure.txt"), new File("C:\\Tests\\secure.txt.aes"), key);
new AESFiles().decrypt(new File("C:\\Tests\\secure.txt.aes"), new File("C:\\Tests\\secure.txt.1"), key);
}
}
So my question is, why the decrypt function only read the first 16 bytes ?
This is very subtle. Your problem is that you are closing your fos before your cos. In your encrypt(...) method you are doing:
} finally {
fos.close();
cos.close();
fis.close();
}
That closes the FileOutputStream out from under the CipherOutputStream so the final padded block of encrypted output never gets written to the output file. If you close the fos after the cos then your code should work fine.
Really, you should consider doing something like:
FileOutputStream fos = null;
CipherOutputStream cos = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(inputFile);
fos = new FileOutputStream(outputFile);
cos = new CipherOutputStream(fos, cipher);
// once cos wraps the fos, you should set it to null
fos = null;
...
} finally {
if (cos != null) {
cos.close();
}
if (fos != null) {
fos.close();
}
if (fis != null) {
fis.close();
}
}
FYI: org.apache.commons.io.IOUtils has a great closeQuietly(...) method which handles null checks and catches the exceptions for you.