Solved

Things to note for DES encryption/decryption using Java

Posted on 2009-05-06
30
767 Views
Last Modified: 2012-05-06
I am using the following class for DES encryption/decryption.

Somehow the other party (using some other classes/program) was unable to decrypt the encrypted file i sent to him. He is using DES as well.

May I know what are the field/values which i should check against his? (eg. passphrase, block size etc)

import java.io.InputStream;

import java.io.OutputStream;

import java.io.UnsupportedEncodingException;

import java.security.SecureRandom;

import java.security.spec.AlgorithmParameterSpec;

import java.security.spec.KeySpec;
 

import javax.crypto.Cipher;

import javax.crypto.CipherInputStream;

import javax.crypto.CipherOutputStream;

import javax.crypto.IllegalBlockSizeException;

import javax.crypto.SecretKey;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.PBEKeySpec;

import javax.crypto.spec.PBEParameterSpec;
 

public class DesEncrypter {

	Cipher ecipher;

	Cipher dcipher;

	byte[] salt = {(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32, (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03};

    //byte[] salt = new byte[16];

    

    

	int iterationCount = 19;

	byte[] buf = new byte[1024];
 

	DesEncrypter(SecretKey key) {

		try {

			SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");

			sr.nextBytes(salt); 

			ecipher = Cipher.getInstance("DES");

			dcipher = Cipher.getInstance("DES");

			ecipher.init(Cipher.ENCRYPT_MODE, key);

			dcipher.init(Cipher.DECRYPT_MODE, key);
 

		} catch (javax.crypto.NoSuchPaddingException e) {

		} catch (java.security.NoSuchAlgorithmException e) {

		} catch (java.security.InvalidKeyException e) {

		}

	}

	

	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) {

		} catch (java.io.IOException e) {

		}

		return null;

	}
 

	public String decrypt(String str) {

		try {

			// Decode base64 to get bytes

			//byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);

			byte[] plaindecrypt = dcipher.doFinal(str.getBytes());
 

			// Decrypt

			//byte[] utf8 = dcipher.doFinal(dec);
 

			// Decode using utf-8

			//return new String(utf8, "UTF8");

			return new String(plaindecrypt, "UTF8");

		} catch (javax.crypto.BadPaddingException e) {

		} catch (IllegalBlockSizeException e) {

		} catch (UnsupportedEncodingException e) {

		} catch (java.io.IOException e) {

		}

		return null;

	}

	

	public void encryptFile(InputStream in, OutputStream out) {

        try {

            // Bytes written to out will be encrypted

            out = new CipherOutputStream(out, ecipher);
 

            // Read in the cleartext bytes and write to out to encrypt

            int numRead = 0;

            while ((numRead = in.read(buf)) >= 0) {

                out.write(buf, 0, numRead);

            }

            out.close();

        } catch (java.io.IOException e) {

        }

    }

	

	public void decryptFile(InputStream in, OutputStream out) {

        try {

            // Bytes read from in will be decrypted

            in = new CipherInputStream(in, dcipher);
 

            // Read in the decrypted bytes and write the cleartext to out

            int numRead = 0;

            while ((numRead = in.read(buf)) >= 0) {

                out.write(buf, 0, numRead);

            }

            out.close();

        } catch (java.io.IOException e) {

        }

    }

}

Open in new window

0
Comment
Question by:edisonffs
  • 11
  • 10
  • 9
30 Comments
 
LVL 86

Accepted Solution

by:
CEHJ earned 250 total points
ID: 24312383
You need to ensure you're using the same block size and padding
0
 
LVL 92

Expert Comment

by:objects
ID: 24312418
I assume you can decrypt it, is that correct?

What are they using to decrypt?

0
 
LVL 92

Assisted Solution

by:objects
objects earned 250 total points
ID: 24312446
>                         return new sun.misc.BASE64Encoder().encode(enc);

you base64 encode the bytes when you encode, make sure the receiver is aware of that (and they are using utf8)
(and you don't base64 decode when u decrypt)

0
 

Author Comment

by:edisonffs
ID: 24312589
I have ensured that the other party is using a block size of 8 bytes (64-bit) as well
(let's ignore the decryption because i will doing the encryption only)

thus, i will get the other party to check on the following as well:
- Decode using base64 and UTF-8

any other field/values should i verify as well?
0
 
LVL 92

Expert Comment

by:objects
ID: 24312602
> any other field/values should i verify as well?

that should be sufficient
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24312604
>>
thus, i will get the other party to check on the following as well:
- Decode using base64 and UTF-8
>>

No need. You're not using that to encrypt the file.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24312626
You might try to do a binary dump of the key at both ends and make sure you're using the same one
0
 

Author Comment

by:edisonffs
ID: 24312636
guess it's a little confusing here.
let me summarized and see if i get the idea right

if i am using encrypt(), i should check with the other party that he is decoding using Base64 and UTF-8

if i am using encryptFile(), there's no need to check for the character decoding.

So if i am using encryptFile(), what should the receiving party ensure?
0
 
LVL 92

Expert Comment

by:objects
ID: 24312674
try the following if it the file encryption you are having a problem with

http://www.exampledepot.com/egs/javax.crypto/DesFile.html?l=rel

let me know how it goes

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24312676
All correct.

>>So if i am using encryptFile(), what should the receiving party ensure?

No harm in taking the md5 sum first at both ends to make sure they got exactly what you sent
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24312686
>>what should the receiving party ensure?

Oh and of course what i said a minute ago - that they are using the exact same key as you are
0
 

Author Comment

by:edisonffs
ID: 24312695
objects:
I will try that out

CEHJ:
So i just need to ensure that the other party is using PBEWithMD5AndDES as well?
0
 
LVL 92

Expert Comment

by:objects
ID: 24312725
yes it goes without saying that both sides need to be using the same encryption method and key/pass phrase :)

0
 

Author Comment

by:edisonffs
ID: 24350961
objects:

The example you've given me earlier (http://www.exampledepot.com/egs/javax.crypto/DesFile.html?l=rel) , the SecretKey object seems to be "auto generated", but my application's requirement is  to use passphrase method to encrypt file stream.

there's a another link to your example (http://www.exampledepot.com/egs/javax.crypto/PassKey.html?l=rel). this is the one which i have been using all along, and doesn't seem to be working.

Possible to advice me on how to integrate both methods (which i think should be the solution to the problem) ?
0
 
LVL 92

Expert Comment

by:objects
ID: 24351262
you didn't answer my earlier question regards how it is getting decrypted at the other end
Also can you decrypt the file once it is encrypted

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:edisonffs
ID: 24352004
objects:

the other end replied that they are decrypting in DES Cipher Block Chaining (CBC) Mode
not sure if this is what you are looking for...

are you referring to the file which i encrypt using my orignal DESEncrypter class (which i posted)?
Yes, i was able to encrypt and decrypt with that
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24352035
edisonffs, this is very confusing - please clarify

>>Somehow the other party (using some other classes/program) was unable to decrypt the encrypted file i sent to him.

>>
are you referring to the file which i encrypt using my orignal DESEncrypter class (which i posted)?
Yes, i was able to encrypt and decrypt with that
>>
0
 
LVL 92

Expert Comment

by:objects
ID: 24352070
> are you referring to the file which i encrypt using my orignal DESEncrypter class (which i posted)?

yes

> the other end replied that they are decrypting in DES Cipher Block Chaining (CBC) Mode

you appear to be using the wrong algorithm, try instead using "PBEWithMD5AndDES/CBC/PKCS5Padding"

0
 

Author Comment

by:edisonffs
ID: 24352081
CEHJ

>>Somehow the other party (using some other classes/program) was unable to decrypt the encrypted file i sent to him.

The other party have their own software to perform decryption. They were unable to decrypt the file which i sent them.

>> are you referring to the file which i encrypt using my orignal DESEncrypter class (which i posted)?
Yes, i was able to encrypt and decrypt with that

Not really sure what objects meant.
If i were to perform encryption/decryption locally using the DESEncrypter class which i posted, i will have no problems with it.
0
 

Author Comment

by:edisonffs
ID: 24352129
objects:

may i know where should i change it in my DESEncrypter class to use "PBEWithMD5AndDES/CBC/PKCS5Padding"?
0
 
LVL 92

Expert Comment

by:objects
ID: 24352648
>             SecretKey key = SecretKeyFactory.getInstance(
                "PBEWithMD5AndDES").generateSecret(keySpec);

there

0
 

Author Comment

by:edisonffs
ID: 24362500
objects:

I tried and i get the following exception:

java.lang.NullPointerException
      at javax.crypto.CipherOutputStream.write(DashoA12275)
      at DesEncrypter.encryptFile(DesEncrypter.java:110)
      at TestDES.main(TestDES.java:32)
0
 
LVL 92

Expert Comment

by:objects
ID: 24371680
sorry, my bad. should be:

SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance("PBEWithMD5AndDES/CBC/PKCS5Padding");
dcipher = Cipher.getInstance("PBEWithMD5AndDES/CBC/PKCS5Padding");


0
 

Author Comment

by:edisonffs
ID: 24372380
objects:

The programs compiles perfectly...

But here's another bomb from the other party.
The padding scheme they are using is called "OneAndZeroes"

And they are actually using a Perl script to do encryption/decryption (pls see attached)

May i know how to amend my class in that case?


#!/usr/bin/perl -w

use strict;

require Crypt::CBC;

require Crypt::DES;

my $algorithm = 'Crypt::DES';

# Usage: filecrypt [e|d] [key] [blocksize] [infile] [outfile]

if(scalar(@ARGV) != 5)

{

  print("Usage: $0 [e|d] [key] [blocksize] [infile] [outfile]\n");

  print("\t e         encrypt infile\n");

  print("\t d         decrypt infile\n");

  print("\t key       cryption key, 8 characters\n");

  print("\t blocksize blocksize filling\n");

  print("\t infile    input file to encrypt/decrypt\n");

  print("\t outfile   output file\n");

  exit 1;

}
 

my $crypt     = $ARGV[0];

my $key       = $ARGV[1];

my $blocksize = $ARGV[2];

my $infile    = $ARGV[3];

my $outfile   = $ARGV[4];

# Create the cipher

my $cipher = Crypt::CBC->new({'key'            => $key,

			      'cipher'         => $algorithm,

			      'iv'             => '',

			      'regenerate_key' => 0,

			      'padding'        => 'oneandzeroes',

			      'prepend_iv'     => 0

			      });

my $input = '';

my $output = '';

$| = 1;

# Read the in file

print("Reading input file...");

open (IN, $infile) or die("Error: No such file: $infile\n");

binmode IN unless $infile =~ /\.txt$/;

$input = do { local $/, <IN> };

close IN;

print("done.\n");

if ( "$crypt" eq "e" )

{

    print("Encrypting data...");

    # Padd to blocksize

    #

    my $paddsize = $blocksize - (length($input) % $blocksize);

    $input = $input . "\0" x $paddsize;

	

    # Encrypt data

    #

    $output = $cipher->encrypt($input);

}

elsif ( "$crypt" eq "d" )

{

    print("Decrypting data...");

    # Decrypt data

    #

    $output = $cipher->decrypt($input);

    print("done.\n");

    

    # Remove padding

    #

    print("Removing padding...");

    $output =~ s/\0+$//g;

}

else

{

    print("Invalid parameter\n");

    exit 1;

}

print("done.\n");

# write to out file

print("Writing output to disk...");

open (OUT, ">$outfile") or die

    ("Error: Unable writing to output file!\n");

binmode OUT unless $outfile =~ /\.txt$/;

print (OUT $output);

close (OUT);

print("done.\n");

print("Finished.\n");

Open in new window

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24375264
>>The padding scheme they are using is called "OneAndZeroes"

That's what they say they are going to use, but they don't actually.

The blocksize is chosen as a command line parameter - what do they choose?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24378911
It looks like they're attempting to do the padding whereas the library itself should be doing the padding. If the padding is specified at all (unnecessary) it should be 'standard' as that's the one supported by Java afaik
0
 

Author Comment

by:edisonffs
ID: 24381866
CEHJ:

they are using blocksize of 64
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24383366
OK. I would suggest they parameterize and change/interfere with that Perl library function as little as possible and accept the defaults wherever possible. With any luck, you should be OK then
0
 

Author Comment

by:edisonffs
ID: 24392507
thanks for the effort guys.

i've decided to install Perl on my Solaris machine and came up with a servlet to call the Perl script (provided by the other party) to do the DES encryption

It's a bad design i know ... ..>.<
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24392822
:-)

Well as long as you don't use that Perl script in its present state ...
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
This paper addresses the security of Sennheiser DECT Contact Center and Office (CC&O) headsets. It describes the DECT security chain comprised of “Pairing”, “Per Call Authentication” and “Encryption”, which are all part of the standard DECT protocol.
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now