1 Replies - 2410 Views - Last Post: 27 July 2012 - 10:33 PM

#1 a-gonzalez  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 27-July 12

Trying to use AES on Android "pad block corrupted"

Posted 27 July 2012 - 02:42 PM

I'm having issues decrypting using AES on Android. The Exception message is "pad block corrupted" and / or a "last block incomplete in decryption". Can anybody tell me what I'm doing wrong?

Here is my code class


package nica.gonzalez.sample.aes;

import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class Encryptor
{
	String _key_file;
	String _IV;
	
	public Encryptor(String key_file)
	{
		_key_file = key_file;
	}
	
	public String encrypt(String plain) throws Exception
	{
		Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);
		byte[] encrypted = cipher.doFinal(plain.getBytes());
		
		_IV = Base64.encodeBytes(cipher.getIV());
		
		return new String(encrypted);
	}
	
	public String decrypt(String encrypted) throws Exception
	{
		Cipher cipher = getCipher(Cipher.DECRYPT_MODE);
		byte[] decrypted = cipher.doFinal(encrypted.getBytes());
		
		return new String(decrypted);
	}
	
	private String getEncryption()
	{
		String aes = "AES";
		
		return aes;
	}
	
	private String getProvider()
	{
		String provider = "BC";
		
		return provider;
	}
	
	private String getAlgorithm()
	{
		String algorithm = "AES/CBC/PKCS5Padding"; //, "BC""
		
		return algorithm;
	}
	
	private Integer getStrength()
	{
		Integer size = 128;
		
		return size;
	}
	
	private SecretKeySpec getSKS() throws Exception
	{
		//byte[] raw = new byte[16];
		File key_file = new File(_key_file);
		byte[] key = new byte[(int) key_file.length()];
		SecretKeySpec sks = null;
		
		if (key_file.exists())
		{
			new FileInputStream(key_file).read(key);
		}
		else
		{
			KeyGenerator generator = KeyGenerator.getInstance(getAlgorithm(), getProvider());
			generator.init(getStrength());
			
			SecretKey secret_key = generator.generateKey();
			key = secret_key.getEncoded();
			
			new FileOutputStream(key_file).write(key);
		}
		sks = new SecretKeySpec(key, getEncryption());
		
		return sks;
	}
	
	private Cipher getCipher(Integer mode) throws Exception
	{
		SecretKeySpec sks = getSKS();
		Cipher cipher = Cipher.getInstance(getAlgorithm(), getProvider());
		
		if (mode == Cipher.ENCRYPT_MODE)
		{
			cipher.init(mode, sks);
		}
		else if (mode == Cipher.DECRYPT_MODE)
		{
			cipher.init(mode, sks, new IvParameterSpec(Base64.decode(_IV)));
		}
		return cipher;
	}
	
	private String toHex(byte[] buffer)
	{
		StringBuffer string_buffer = new StringBuffer(buffer.length * 2);
		Integer index;
		
		for (index = 0; index < buffer.length; index++)
		{
			if (((int) buffer[index] & 0xff) < 0x10)
			{
				string_buffer.append("0");
			}
			string_buffer.append(Long.toString((int) buffer[index] & 0xff, 16));
		}
		return string_buffer.toString();
	}
}





This is how I'm calling the encrypt / decrypt methods:


@Override
    public void onCreate(Bundle sis)
    {
    	Log.d(getResources().getString(R.string.tag), "in onCreate...");
    	
        super.onCreate(sis);
        
        setContentView(R.layout.activity_main);
        
        getActionBar().setDisplayHomeAsUpEnabled(true);
        
        String key_file = getApplicationContext().getFilesDir().getPath().concat("/").concat(getResources().getString(R.string.key_file));
        
        Log.d(getResources().getString(R.string.tag), "Key File: ".concat(key_file));
        
        Encryptor encryptor = new Encryptor(key_file);
        
        Log.d(getResources().getString(R.string.tag), "Encryptor created...");
        
        String encrypted = null;
        
        try
        {
        	Log.d(getResources().getString(R.string.tag), " * ** * ** * encrypting * ** * ** * ");
        	
        	String original = getResources().getString(R.string.test_encrypt_text);
        	
        	Log.d(getResources().getString(R.string.tag), "Before : ".concat(original));
        	
        	encrypted = encryptor.encrypt(original);
        	
        	Log.d(getResources().getString(R.string.tag), "After : ".concat(encrypted));
        }
        catch (Exception exception)
        {
        	Log.d(getResources().getString(R.string.tag), exception.getMessage());
        	
        	exception.printStackTrace();
        }
        
        String plain;
        
        try
        {
        	Log.d(getResources().getString(R.string.tag), " * ** * ** * decrypting * ** * ** * ");
        	Log.d(getResources().getString(R.string.tag), "Before : ".concat(encrypted));
        	
        	plain = encryptor.decrypt(encrypted);
        	
        	Log.d(getResources().getString(R.string.tag), "After: ".concat(plain));
        }
        catch (Exception exception)
        {
        	Log.d(getResources().getString(R.string.tag), exception.getMessage());
        	
        	exception.printStackTrace();
        }
    }




Is This A Good Question/Topic? 0
  • +

Replies To: Trying to use AES on Android "pad block corrupted"

#2 blackcompe  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1152
  • View blog
  • Posts: 2,530
  • Joined: 05-May 05

Re: Trying to use AES on Android "pad block corrupted"

Posted 27 July 2012 - 10:33 PM

This should help. Check out the AEStest class in the BC source. I'm also a bit concerned as to why you didn't initialize the cipher with an IV for encryption (yet you did for decryption) if you're using CBC mode. I'm not completely sure that's necessary, but I'm pretty sure. Perhaps that's the source of the padding error.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1