I wonder if you're allowed to reuse the same key (declared as "final") between encoding and decoding.
Other than that, and Nikolay's advice, here is what I do: private static final byte[] SALT = { ... }; private static final int COUNT = 10; private static final byte[] REFERENCE_DATA = "Reference data".getBytes(US_ASCII); private static final String ALGORITHM = "PBEWithMD5AndDES"; public OutputStream wrapCipherOutputStream(OutputStream streamOut, String password) throws IOException, GeneralSecurityException { PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); PBEParameterSpec pbeParamSpec = new PBEParameterSpec(SALT, COUNT); SecretKeyFactory keyFac = SecretKeyFactory.getInstance(ALGORITHM); SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec); Cipher pbeCipher = Cipher.getInstance(ALGORITHM); pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec); /* * Write predefined data first (see the reading code) */ byte[] output = pbeCipher.doFinal(REFERENCE_DATA); streamOut.write(output.length); streamOut.write(output); return new CipherOutputStream(streamOut, pbeCipher); } public InputStream wrapCipherInputStream(InputStream streamIn, String password) throws IOException, GeneralSecurityException { PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); PBEParameterSpec pbeParamSpec = new PBEParameterSpec(SALT, COUNT); SecretKeyFactory keyFac = SecretKeyFactory.getInstance(ALGORITHM); SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec); Cipher pbeCipher = Cipher.getInstance(ALGORITHM); pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec); /* * Read a predefined data block. If the password is incorrect, we'll get a security * exception here. Without this, we will only get an IOException later when reading * the CipherInputStream, which is not specific enough for a good error message. */ int count = streamIn.read(); if (count <= 0 || count > 1024) { throw new IOException( mContext.getString(R.string.backup_restore_error_bad_file)); } byte[] input = new byte[count]; streamIn.read(input); pbeCipher.doFinal(input); return new CipherInputStream(streamIn, pbeCipher); } -- Kostya 2011/10/2 Nikolay Elenkov <nikolay.elen...@gmail.com> > On Mon, Oct 3, 2011 at 2:36 AM, mac-systems <jens.h...@gmx.de> wrote: > > I try to read encrypted data, but always get java.io.IOException: last > > block incomplete in decryption > > Dump the encrypted stream to file and check its length. It must be a > multiple of 8 (block size is 64 bits for DES) for decryption to work. > If it's not, check your code, you probably have a bug somewhere. > > And don't use DES if you can avoid it. > > -- > You received this message because you are subscribed to the Google > Groups "Android Developers" group. > To post to this group, send email to android-developers@googlegroups.com > To unsubscribe from this group, send email to > android-developers+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/android-developers?hl=en > -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en