How can we do Triple Decryption in java? - java

I am using a MOL API for VOUCHER recharges. Which returns a PIN number in response is successful. That PIN number will be an encrypted text and I need to triple decrypt it!
I contacted the API support, They provided with the code below:
byte[] PinBytes = Base64.decodeBase64(encryptedText.getBytes("utf-8"));
byte[] VectorBytes = Base64.decodeBase64(vectorKey.getBytes("utf-8"));
byte[] SecretKeyBytes = Base64.decodeBase64(secretKey.getBytes("utf-8"));
TripleDESProvider = CreateTripleDESCryptographicProvider(VectorBytes, SecretKeyBytes)
DecryptedBytes = TripleDESProvider.Decrypt(PinBytes)
Here VectorBytes and SecretKeyBytes are security keys provided by them and PinBytes are the response PIN number which is encrypted.
I googled while I was not able to get a correct solution with these three parameters. Any help, please?
I tried this:
try
{
String encryptedText = "FN0hbSrVzkqhe+w2rQefAQ==";
String vectorKey = "7EsBtzAJjMg=";
//32 bit key
String secretKey = "08061052989102040806105298910204";
byte[] PinBytes = Base64.decodeBase64(encryptedText.getBytes("utf-8"));
byte[] VectorBytes = Base64.decodeBase64(vectorKey.getBytes("utf-8"));
byte[] SecretKeyBytes = Base64.decodeBase64(secretKey.getBytes("utf-8"));
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(SecretKeyBytes);
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;)
{
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(VectorBytes);
final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
//final byte[] encData = new sun.misc.BASE64Decoder().decodeBuffer(message);
final byte[] plainText = decipher.doFinal(PinBytes);
System.out.println(plainText.toString());
}
catch (java.security.InvalidAlgorithmParameterException e) { System.out.println("Invalid Algorithm"); }
catch (javax.crypto.NoSuchPaddingException e) { System.out.println("No Such Padding"); }
catch (java.security.NoSuchAlgorithmException e) { System.out.println("No Such Algorithm"); }
catch (java.security.InvalidKeyException e) { System.out.println("Invalid Key"); }
catch (BadPaddingException e) { System.out.println("Invalid Key");}
catch (IllegalBlockSizeException e) { System.out.println("Invalid Key");}
catch (UnsupportedEncodingException e) { System.out.println("Invalid Key");}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Error is Invalid KEY
The document they provide is;
Convert Encrypted Pin into Byte Array from Base64 format
PinBytes = ConvertFromBase64String ("FN0hbSrVzkqhe+w2rQefAQ==")
As Vector Key and Secret Key are provided in Base64 format, thus we need to convert both data into Byte Array as well
VectorBytes = ConvertFromBase64String ("xxxxxxxxx")
SecretKeyBytes = ConvertFromBase64String ("xxxxxxxxxxxx")
Please create your Triple DES Cryptographic Provider and set your IV byte array and Secret Key byte array into your Provider.
TripleDESProvider = CreateTripleDESCryptographicProvider(VectorBytes, SecretKeyBytes)
Please invokes Triple DES Provider decrypt method.
DecryptedBytes = TripleDESProvider.Decrypt(PinBytes)
Finally convert back decrypted bytes back to string.
ConvertToString(DecryptedBytes)
The result should be 8157151550.

I am not sure if this is the right approach but with AES encryption it works. They provided you the vector, use it to initialize the IVParameterSpec, then create Key object and Cipher instance:
// this is the encripted text
byte[] PinBytes = Base64.decodeBase64(encryptedText.getBytes("utf-8"));
byte[] VectorBytes = Base64.decodeBase64(vectorKey.getBytes("utf-8"));
byte[] SecretKeyBytes = Base64.decodeBase64(secretKey.getBytes("utf-8"));
// initialize the vector with the one you receive
IvParameterSpec spec = new IvParameterSpec(VectorBytes);
// create the key. DESede should be correct, but if it doesn't work try also with DES
Key key = new SecretKeySpec(SecretKeyBytes, "DESede");
// Initialize the cipher
Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
// decrypt the string
c.init(Cipher.DECRYPT_MODE, key, spec);
byte[] decodedDecryptedBytes = c.doFinal(PinBytes);
Base64 object i use is from apache common codec library, but you can use the library you want.

Finally, I Got this answer with same provided secretKey!!
try
{
byte[] PinBytes = Base64.decodeBase64(encryptedText);
byte[] VectorBytes = Base64.decodeBase64(vectorKey);
byte[] SecretKeyBytes = Base64.decodeBase64(secretKey);
// initialize the vector with the one you receive
IvParameterSpec spec = new IvParameterSpec(VectorBytes);
// create the key. DESede should be correct, but if it doesn't work try also with DES
Key key = new SecretKeySpec(SecretKeyBytes, "DESede");
// Initialize the cipher
Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
// decrypt the string
c.init(Cipher.DECRYPT_MODE, key, spec);
byte[] decodedDecryptedBytes = c.doFinal(PinBytes);
return new String(decodedDecryptedBytes, "UTF-8");
}
catch (java.security.InvalidAlgorithmParameterException e) { System.out.println("Invalid Algorithm"); }
catch (javax.crypto.NoSuchPaddingException e) { System.out.println("No Such Padding"); }
catch (java.security.NoSuchAlgorithmException e) { System.out.println("No Such Algorithm"); }
catch (java.security.InvalidKeyException e) { System.out.println("InvalidKeyException : Invalid Key"); }
catch (BadPaddingException e) { System.out.println("BadPaddingException : Invalid Key");}
catch (IllegalBlockSizeException e) { System.out.println("IllegalBlockSizeException : Invalid Key");}
catch (UnsupportedEncodingException e) { System.out.println("UnsupportedEncodingException : Invalid Key");}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
The Mistake was doing this:
byte[] SecretKeyBytes = Base64.decodeBase64(secretKey.getBytes("utf-8"));
I don't know why this happens! But by removing that I got the answer!!

Related

Getting a bunch of extra output when decrypting an encrypted file. What could be the problem in my code?

I'm new to cryptography and this here is the code that I wrote filling in the skeleton code provided by my assigner(please don't mind the structure). I describe the problem below this code.
public class FileEncryptor {
private static final String progName = "FileEncryptor";
private static final int bufSize = 128;
public static void main(String[] args) {
BufferedInputStream in = null; // A buffered input stream to read from
BufferedOutputStream out = null; // And a buffered output stream to write to
SecretKeyFactory kf = null; // Something to create a key for us
KeySpec ks = null; // This is how we specify what kind of key we want it to generate
byte[] salt = new byte[20]; // Some salt for use with PBKDF2, only not very salty
SecretKey key = null; // The key that it generates
Cipher cipher = null; // The cipher that will do the real work
SecretKeySpec keyspec = null; // How we pass the key to the Cipher
int bytesRead = 0; // Number of bytes read into the input file buffer
// First, check the user has provided all the required arguments, and if they haven't, tell them then exit
if(args.length != 4) {
printUsageMessage(); System.exit(1);
}
// Open the input file
try {
in = new BufferedInputStream(new FileInputStream(args[1]));
} catch (FileNotFoundException e) {
printErrorMessage("Unable to open input file: " + args[1], null);
System.exit(1);
}
// And then the output file
try {
out = new BufferedOutputStream(new FileOutputStream(args[2]));
} catch (FileNotFoundException e) {
printErrorMessage("Unable to open output file: " + args[2], e);
System.exit(1);
}
// Create a PBKDF2 secret key factory
String algorithm = "PBKDF2WithHmacSHA256";
try {
kf = SecretKeyFactory.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
printErrorMessage("Specified algorithm could not be found: " + algorithm , e);
System.exit(1);
}
// Set up a KeySpec for password-based key generation of a 128-bit key
ks = new PBEKeySpec(args[3].toCharArray(),salt,4096, 128);
// Now run the passphrase through PBKDF2 to get the key
try {
key = kf.generateSecret(ks);
} catch (InvalidKeySpecException e) {
printErrorMessage("The key spec provided is invalid: " + keyspec, e);
System.exit(1);
}
// Get the byte encoded key value as a byte array
byte[] aeskey = key.getEncoded();
// Now generate a Cipher object for AES encryption in ECBC mode with PKCS #5 padding
// Use ECB for the first task, then switch to CBC for versions 2 and 3
try {
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
printErrorMessage("No Such Algorithm Exception when creating main cipher", e);
System.exit(2);
} catch (NoSuchPaddingException e) {
printErrorMessage("No Such Padding Exception when creating main cipher",e);
System.exit(2);
}
// Set a variable to indicate whether we're in encrypt or decrypt mode, based upon args[0]
int cipherMode = -1;
char mode = Character.toLowerCase(args[0].charAt(0));
switch (mode) {
case 'e' : cipherMode = Cipher.ENCRYPT_MODE; break;
case 'd' : cipherMode = Cipher.DECRYPT_MODE; break;
default: printUsageMessage(); System.exit(1);
}
// Set up a secret key specification, based on the 16-byte (128-bit) AES key array previously generated
keyspec = new SecretKeySpec(aeskey, "AES");
// Now initialize the cipher in the right mode, with the keyspec and the ivspec
try {
cipher.init(cipherMode, keyspec);
} catch (InvalidKeyException e) {
printErrorMessage("Invalid Key Spec",e); System.exit(2);
}
// Set up some input and output byte array buffers
byte[] inputBuffer = new byte[bufSize];
byte[] outputBuffer = null;
// "Prime the pump" - we've got to read something before we can encrypt it
// and not encrypt anything if we read nothing.
try {
bytesRead = in.read(inputBuffer);
} catch (IOException e1) {
printErrorMessage("Error reading input file " + args[1],e1); System.exit(1);
}
// As long as we've read something, loop around encrypting, writing and reading
// bytesRead will be zero if nothing was read, or -1 on EOF - treat them both the same
while (bytesRead > 0) {
byte[] input = inputBuffer;
// Now encrypt this block
outputBuffer = cipher.update(input);
// Write the generated block to file
try {
out.write(outputBuffer);
} catch (IOException e1) {
printErrorMessage("Error writing to output file " + args[2],e1); System.exit(1);
}
// And read in the next block of the file
try {
bytesRead = in.read(inputBuffer);
} catch (IOException e1) {
printErrorMessage("Error reading input file " + args[1],e1); System.exit(1);
}
}
// Now do the final processing
try {
outputBuffer = cipher.doFinal(outputBuffer);
} catch (IllegalBlockSizeException e2) {
printErrorMessage("Illegal block size encountered while doing final processing: " + outputBuffer.length , e2);
System.exit(1);
} catch (BadPaddingException e2) {
printErrorMessage("Bad Padding found", e2);
System.exit(1);
}
// Write the final block of output
try {
out.write(outputBuffer);
} catch (IOException e1) {
printErrorMessage("Error on final write to output file " + args[2],e1); System.exit(1);
}
// Close the output files
try {
in.close();
out.close();
} catch (IOException e1) {
printErrorMessage("Error closing file", e1);
}
}
}
For convenience I omitted the printErrorMessage() and printUsageMessage() methods.
This here seems to be the problem; I am getting a BadPaddingException and though the code catches that exception I do not know how to handle that exception or what to do with it. I tried removing the System.exit(1) line from my code in final processing but then the output files comes out twice the size of my encrypted file which is 256 bytes regardless of the size of my input files(having size less than 256 bytes). So, if my input file contains:
hello there
And I encrypt it using key as the passphrase I get my output file containing something like this:
9`ÃLå7}
syXÀ¢Èì´^¾Õn¾AXëC~9‹`Èì´^¾Õn¾AXëC~9‹`Èì´^¾Õn¾AXëC~9‹`Èì´^¾Õn¾AXëC~9‹`Èì´^¾Õn¾AXëC~9‹`Èì´^¾Õn¾AXëC~9‹`Èì´^¾Õn¾AXëC~9‹`0‹ó‚±G¸Y·IñåsòQœ ÙÞç„ò;uîðpoîœ ÙÞç„ò;uîðpoîœ ÙÞç„ò;uîðpoîœ ÙÞç„ò;uîðpoîœ ÙÞç„ò;uîðpoîœ ÙÞç„ò;uîðpoîœ ÙÞç„ò;uîðpoÄQé±uTö/ژͤ
And now when I decrypt this file using the same passphrase key I get something like this:
hello there 9`Ì巽
syXÀ¢Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`Ȭ´^¾ծ¾AX냾9`
How can I get rid of this shit-storm that's trailing my decrypted text?
All helps and suggestions will be appreciated. Thanks.

Java - Decryption : javax.crypto.BadPaddingException

I get this warning:
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
Any ideas what causes this? Here are my encryption and decryption code. I have looked at a variety of different answers on StackOverflow but I was unable to find one that actually works.
private static Cipher ecipher;
private static Cipher dcipher;
private static SecretKey key;
public static void Menu() {
try {
// generate secret key using DES algorithm
key = KeyGenerator.getInstance("DES").generateKey();
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
// initialize the ciphers with the given key
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
} catch (NoSuchAlgorithmException e) {
System.out.println("No Such Algorithm:" + e.getMessage());
return;
} catch (NoSuchPaddingException e) {
System.out.println("No Such Padding:" + e.getMessage());
return;
} catch (InvalidKeyException e) {
System.out.println("Invalid Key:" + e.getMessage());
return;
}
}
public static String encrypt(String WordToEncrypt) {
Menu();
try {
// encode the string into a sequence of bytes using the named charset
// storing the result into a new byte array.
byte[] utf8 = WordToEncrypt.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
// encode to base64
enc = BASE64EncoderStream.encode(enc);
System.out.println(new String(enc));
return new String(enc);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String decrypt(String WordToDecrypt) {
Menu();
try {
// decode with base64 to get bytes
byte[] dec = BASE64DecoderStream.decode(WordToDecrypt.getBytes());
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF8");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
You call Menu once in the encryption code and once in the decryption code. Since you generate the key randomly for both encryption and decryption, the key will differ and your code will fail.
Don't keep Cipher instances around, preferably not even in fields, but certainly not in class fields. DES is old; too old. Use AES - using DES isn't any easier than AES.

Decrypt a string with DES in PHP that's been encrypted by Java

I've been banging my head against the wall trying to figure out exactly how to format everything to decrypt this string in PHP that's been encrypted in a custom Java class.
Here's the relevent functions from the Java class. The "salt" variable is a class variable byte array set earlier:
public DesEncrypter(String passPhrase) {
try {
// Create the key
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt,
iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES")
.generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameter to the ciphers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt,
iterationCount);
// Create the ciphers
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (java.security.InvalidAlgorithmParameterException e) {
} catch (java.security.spec.InvalidKeySpecException e) {
} catch (javax.crypto.NoSuchPaddingException e) {
} catch (java.security.NoSuchAlgorithmException e) {
} catch (java.security.InvalidKeyException e) {
}
}
public String encrypt(String str) {
try {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return new sun.misc.BASE64Encoder().encode(enc);
} catch (javax.crypto.BadPaddingException e) {
} catch (IllegalBlockSizeException e) {
} catch (UnsupportedEncodingException e) {
}
return null;
}
public String decrypt(String str) {
try {
// Decode base64 to get bytes
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
// Decrypt
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch( Exception ex) {
ex.printStackTrace(System.err);
}
return null;
}
And here's what I have so far in PHP (FYI, I'm using this encryption library in PHP https://github.com/phpseclib/phpseclib):
$app->get('/decrypt', function () use ($app) {
$data = '3aCRLRd3srA/QF4MQb0D+P==';
$salt = pack('nvc*', 0xB7, 0x9A, 0xC1, 0x34, 0x26, 0x89, 0xW3, 0x30);
$secret = "secret";
$keyLength = 16;
$cipher = new Crypt_DES(CRYPT_DES_MODE_CBC);
$cipher->setPassword($secret, 'pbkdf2', 'md5', $salt, $keyLength);
var_dump($cipher->decrypt($data));
});
Right now it's dumping out a bunch of binary, which I've tried base64_decoding, but that doesn't do anything either.
If key.getAlgorithm() is "DES" then you need to provide a fully specified Cipher name like "DES/CBC/PKCS5Padding".
You will also need to provide the IV if it is non-null. Usually the IV is prepended to the ciphertext.
You can get the IV with cipher.getIV() and set with $cipher->setIV('...');.

Missing argument while converting RijndaelManaged in java

while converting a .net code of decryption to java I got an exception
Exception in thread "main" java.lang.IllegalArgumentException: Missing argument
at javax.crypto.spec.SecretKeySpec.<init>(DashoA13*..)
at com.motorola.gst.DecryptTest3.Decrypt(DecryptTest3.java:90)
at com.motorola.gst.DecryptTest3.main(DecryptTest3.java:36)
well I'm trying it for the first time both decryption and converting a .net code to java
here is the .net code that I'm trying to convert
private static string Decrypt(string encryptedText, string completeEncodedKey, int keySize)
{
RijndaelManaged aesEncryption = new RijndaelManaged();
aesEncryption.KeySize = keySize;
aesEncryption.BlockSize = 128;
aesEncryption.Mode = CipherMode.CBC;
aesEncryption.Padding = PaddingMode.PKCS7;
aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);
aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]);
ICryptoTransform decrypto = aesEncryption.CreateDecryptor();
byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length);
return ASCIIEncoding.UTF8.GetString(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length));
}
I went through many posts and found Decrypting bytes encrypted by .NET's RijndaelManaged using Java is more related to my case.
I followed these and wrote my decrypt function as ::
private static String Decrypt(String encryptedText, String completeEncodedKey,int keySize) {
//get completeEncodedKey in bytes and then to string
String decodedcompleteEncodedKey = StringUtils.newStringUtf8(Base64.decodeBase64(completeEncodedKey));
System.out.println("Decoded completeEncodedKey Key :: "+decodedcompleteEncodedKey);
int indexComma = decodedcompleteEncodedKey.indexOf(',');
System.out.println("COmma Index :: "+indexComma);
String IV = decodedcompleteEncodedKey.substring(0, indexComma);
String Key = decodedcompleteEncodedKey.substring(indexComma+1,decodedcompleteEncodedKey.length());
System.out.println("IV::: "+IV);
System.out.println("Key::: "+Key);
byte[] sessionKey = null;
byte[] iv = null ;
byte[] plaintext = encryptedText.getBytes();
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv));
byte[] ciphertext = cipher.doFinal(plaintext);
} catch (IllegalBlockSizeException e) {
System.out.println("IllegalBlockSizeException");
e.printStackTrace();
} catch (BadPaddingException e) {
System.out.println("BadPaddingException");
e.printStackTrace();
} catch (InvalidKeyException e) {
System.out.println("InvalidKeyException");
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
System.out.println("InvalidAlgorithmParameterException");
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException");
e.printStackTrace();
} catch (NoSuchPaddingException e) {
System.out.println("NoSuchPaddingException");
e.printStackTrace();
}
return null;
}
but now I'm getting Exception in thread "main" java.lang.IllegalArgumentException: Missing argument.
can anyone help me getting these errors fixed.
any help would be appreciated.
thanks!!
For me the problem was calling new SecretKeySpec(sessionKey, "AES") with sessionKey = null.

Encrypting and decrypting a zip file in Android?

I am using this code: http://examples.javacodegeeks.com/core-java/crypto/encrypt-decrypt-file-stream-with-des for encrypting my zip files used in android app .It is working really fine with the zip files when I tried it using java code ,But when I tried same methods in Android app - It decrypts the file but file I get is corrupted and unable to open it.
Log:
04-19 10:58:25.711: W/System.err(6752): net.lingala.zip4j.exception.ZipException: zip headers not found. probably not a zip file
04-19 10:58:25.721: W/System.err(6752): at net.lingala.zip4j.core.HeaderReader.readEndOfCentralDirectoryRecord(HeaderReader.java:122)
And when I try to open the same file on Windows with winzip it displays:
Does not appear to be a valid archive file.
Update::
public class EncryptDecryptFileStreamWithDES {
private static Cipher ecipher;
private static Cipher dcipher;
// 8-byte initialization vector
private static byte[] iv = {
(byte)0xB2, (byte)0x12, (byte)0xD5, (byte)0xB2,
(byte)0x44, (byte)0x21, (byte)0xC3, (byte)0xC3
};
public static void call() {
try {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
// encrypt(new FileInputStream("C:\\Users\\Admin\\Desktop\\zipped\\4.zip"), new FileOutputStream("C:\\Users\\Admin\\Desktop\\zipped\\4.dat"));
// decrypt(new FileInputStream("C:\\Users\\Admin\\Desktop\\zipped\\4.dat"), new FileOutputStream("C:\\Users\\Admin\\Desktop\\zipped\\4new.zip"));
//}
//catch (FileNotFoundException e) {
//System.out.println("File Not Found:" + e.getMessage());
//return;
}
catch (InvalidAlgorithmParameterException e) {
System.out.println("Invalid Alogorithm Parameter:" + e.getMessage());
return;
}
catch (NoSuchAlgorithmException e) {
System.out.println("No Such Algorithm:" + e.getMessage());
return;
}
catch (NoSuchPaddingException e) {
System.out.println("No Such Padding:" + e.getMessage());
return;
}
catch (InvalidKeyException e) {
System.out.println("Invalid Key:" + e.getMessage());
return;
}
}
public static void encrypt(InputStream is, OutputStream os) {
try {
call();
byte[] buf = new byte[1024];
// bytes at this stream are first encoded
os = new CipherOutputStream(os, ecipher);
// read in the clear text and write to out to encrypt
int numRead = 0;
while ((numRead = is.read(buf)) >= 0) {
os.write(buf, 0, numRead);
}
// close all streams
os.close();
}
catch (IOException e) {
System.out.println("I/O Error:" + e.getMessage());
}
}
public static void decrypt(InputStream is, OutputStream os) {
try {
call();
byte[] buf = new byte[1024];
// bytes read from stream will be decrypted
CipherInputStream cis = new CipherInputStream(is, dcipher);
// read in the decrypted bytes and write the clear text to out
int numRead = 0;
while ((numRead = cis.read(buf)) > 0) {
os.write(buf, 0, numRead);
}
// close all streams
cis.close();
is.close();
os.close();
}
catch (IOException e) {
System.out.println("I/O Error:" + e.getMessage());
}
}
}
This is the Class which I am using:
The problem is that you use different keys to encrypt and decrypt the file:
1) You call encrypt(..) from somewhere outside the EncryptDecryptFileStreamWithDES, which in its turn calls your call() method, which initializes new key:
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
2) Then you call decrypt(..), which calls your call() method again and you get new SecretKey.
There is no such a problem in the example you used, there is an opposite order of these methods invocations.
To extend this example you need to hold the key between invocation of encrypt(..) and decrypt(..) and then initialize SecretKeySpec with the key stored:
byte[] keyBytes = KeyGenerator.getInstance("AES").getEncoded();
...
SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
Here is a little bit more real-life example.
P.S. As it was mentioned, using DES algorithm is not the best idea, use AES instead.

Categories

Resources