D
Daniel
Hi all,
I am trying to encode text using the java crypto package. When I run it from
the command line, it encrypts/decrypts fine. From the command line, I copy
and paste the encrypted text and save it to a file. I also save the
encrypted text to a database field - varchar (50).
However, when I try to read back from the file or from the database, I get
this error (partial listing):
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input
length (with padding) not multiple of 8 bytes
at com.sun.crypto.provider.SunJCE_h.a(DashoA6275)
at com.sun.crypto.provider.SunJCE_h.b(DashoA6275)
at com.sun.crypto.provider.SunJCE_h.b(DashoA6275)
at com.sun.crypto.provider.SunJCE_ab.b(DashoA6275)
at
com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineDoFinal(DashoA6275)
at javax.crypto.Cipher.doFinal(DashoA6275)
It complains about the padding. I can decrypt fine through the command line.
What is it about saving the cipher text somewhere that makes it throw an
exception. What is the best way to resolve it?
The source is below.
Thanks in advance.
package jfacts.beans.utils;
import java.io.*;
import java.util.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class DesEncrypter
{
private String passPhrase = "";
Cipher ecipher;
Cipher dcipher;
// 8-byte Salt
byte[] salt =
{
( byte ) 0xA9, ( byte ) 0x9B, ( byte ) 0xC8, ( byte ) 0x32,
( byte ) 0x56, ( byte ) 0x35, ( byte ) 0xE3, ( byte ) 0x03
};
// Iteration count
int iterationCount = 19;
public DesEncrypter() throws Exception
{
passPhrase = "testing...";
init( passPhrase );
}
private void init( String passPhrase ) throws Exception
{
// Create the key
KeySpec keySpec = new PBEKeySpec( passPhrase.toCharArray() );
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 );
}
public DesEncrypter( String passPhrase ) throws Exception
{
this.passPhrase = passPhrase;
init( passPhrase );
}
public String encrypt( String str ) throws Exception
{
// 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().encodeBuffer( enc );
}
public String decrypt( String str ) throws Exception
{
// 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" );
}
if ( args.length != 2 || ( !args[0].equals( "-encrypt" ) &&
!args[0].equals( "-decrypt" ) ) )
{
System.out.println( "Usage: -encrypt [enter string to be
encrypted]" );
System.out.println( "Usage: -decrypt [enter string to be
decrypted]" );
System.exit( 0 );
}
String text = args[1];
if ( args[0].equals( "-encrypt" ) )
{
// Create encrypter/decrypter class
String passPhrase = "My Pass Phrase!";
DesEncrypter encrypter = new DesEncrypter( passPhrase );
System.out.println( "pass phrase used to encode: " +
passPhrase );
System.out.println( "plain text: " + text );
// Encrypt
String encrypted = encrypter.encrypt( text );
System.out.println( "encrypted text: " + encrypted );
System.out.println( "size of encrypted text: " +
encrypted.length() );
}
else if ( args[0].equals( "-decrypt" ) )
{
// Create encrypter/decrypter class
String passPhrase = "My Pass Phrase!";
DesEncrypter encrypter = new DesEncrypter( passPhrase );
System.out.println( "pass phrase used to encode: " +
passPhrase );
System.out.println( "plain text: " + text );
// Decrypt
String decrypted = encrypter.decrypt( text );
System.out.println( "decrypted text: " + decrypted );
}
}
I am trying to encode text using the java crypto package. When I run it from
the command line, it encrypts/decrypts fine. From the command line, I copy
and paste the encrypted text and save it to a file. I also save the
encrypted text to a database field - varchar (50).
However, when I try to read back from the file or from the database, I get
this error (partial listing):
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input
length (with padding) not multiple of 8 bytes
at com.sun.crypto.provider.SunJCE_h.a(DashoA6275)
at com.sun.crypto.provider.SunJCE_h.b(DashoA6275)
at com.sun.crypto.provider.SunJCE_h.b(DashoA6275)
at com.sun.crypto.provider.SunJCE_ab.b(DashoA6275)
at
com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineDoFinal(DashoA6275)
at javax.crypto.Cipher.doFinal(DashoA6275)
It complains about the padding. I can decrypt fine through the command line.
What is it about saving the cipher text somewhere that makes it throw an
exception. What is the best way to resolve it?
The source is below.
Thanks in advance.
package jfacts.beans.utils;
import java.io.*;
import java.util.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class DesEncrypter
{
private String passPhrase = "";
Cipher ecipher;
Cipher dcipher;
// 8-byte Salt
byte[] salt =
{
( byte ) 0xA9, ( byte ) 0x9B, ( byte ) 0xC8, ( byte ) 0x32,
( byte ) 0x56, ( byte ) 0x35, ( byte ) 0xE3, ( byte ) 0x03
};
// Iteration count
int iterationCount = 19;
public DesEncrypter() throws Exception
{
passPhrase = "testing...";
init( passPhrase );
}
private void init( String passPhrase ) throws Exception
{
// Create the key
KeySpec keySpec = new PBEKeySpec( passPhrase.toCharArray() );
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 );
}
public DesEncrypter( String passPhrase ) throws Exception
{
this.passPhrase = passPhrase;
init( passPhrase );
}
public String encrypt( String str ) throws Exception
{
// 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().encodeBuffer( enc );
}
public String decrypt( String str ) throws Exception
{
// 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" );
}
if ( args.length != 2 || ( !args[0].equals( "-encrypt" ) &&
!args[0].equals( "-decrypt" ) ) )
{
System.out.println( "Usage: -encrypt [enter string to be
encrypted]" );
System.out.println( "Usage: -decrypt [enter string to be
decrypted]" );
System.exit( 0 );
}
String text = args[1];
if ( args[0].equals( "-encrypt" ) )
{
// Create encrypter/decrypter class
String passPhrase = "My Pass Phrase!";
DesEncrypter encrypter = new DesEncrypter( passPhrase );
System.out.println( "pass phrase used to encode: " +
passPhrase );
System.out.println( "plain text: " + text );
// Encrypt
String encrypted = encrypter.encrypt( text );
System.out.println( "encrypted text: " + encrypted );
System.out.println( "size of encrypted text: " +
encrypted.length() );
}
else if ( args[0].equals( "-decrypt" ) )
{
// Create encrypter/decrypter class
String passPhrase = "My Pass Phrase!";
DesEncrypter encrypter = new DesEncrypter( passPhrase );
System.out.println( "pass phrase used to encode: " +
passPhrase );
System.out.println( "plain text: " + text );
// Decrypt
String decrypted = encrypter.decrypt( text );
System.out.println( "decrypted text: " + decrypted );
}
}