0

I am passing one encrypted key as URL argument and after receiving the key, I am trying to decrypt the key but getting bad arguments exception at a particular portion of the code. I am not understanding where is the issue and how to resolve it. Hereby requesting you to help me on this. I have mentioned the code line where i am getting the error in the console part below.

Source(A legacy java application where generating the encrypted key):

StrongAES strong_AES = new StrongAES();
id = strong_AES.encrypt_Data(user_string_2bEncrypted);
c = strong_AES.count_Cipher();

<a href="url/id=<%=id%>&c=<%=c%>">

StrongAES Class

public class StrongAES {

    byte[] input;
    byte[] cipher_Text;
    SecretKeySpec Key;
    int ctLength;

    public byte[] encrypt_Data(String data){
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        byte[] input = data.getBytes();
        this.input = input;
        byte[] keyBytes = new byte[] {'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y'};

        SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
        this.Key = key;
        byte[] cipherText = null;
        Cipher cipher;
        try {
            cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            cipherText = new byte[cipher.getOutputSize(input.length)];
            int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
            ctLength += cipher.doFinal(cipherText, ctLength);
            this.cipher_Text = cipherText;
            this.ctLength = ctLength;
        ....    
        ....
        return cipherText;
    }
    public int count_Cipher(){
        return this.ctLength;   
    }

Destination(An application written in Spring MVC):

HomeController.java

@RequestMapping(value = "/id={id}", method = RequestMethod.GET)
    public String getMethod(@PathVariable(value = "id") String id ,@RequestParam int c ,ModelMap model, HttpServletRequest request){
         System.out.println("key value is : "+id);
         System.out.println("lenth is :"+c);

        StrongAES strong_AES = new StrongAES();
        String login = null;
        try {
            login = strong_AES.decrypt_Data(id.getBytes(),c);
            System.out.println("decrypted login id is -"+login.toString());
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }

StrongAES Class

public class StrongAES {
            public void encrypt_Data(){

        }

    public String decrypt_Data(byte[] cipherText, int ctLength) throws InvalidAlgorithmParameterException{

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        byte[] keyBytes = new byte[] {'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y'};
        SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
        System.out.println("byte length - "+cipherText.length);
        Cipher cipher;
        byte[] plainText = null;
        try {
            cipher = Cipher.getInstance("AES/ECB/PKCS7Padding","BC");
            cipher.init(Cipher.DECRYPT_MODE, key);

            //decrypt
            plainText = new byte[cipher.getOutputSize(ctLength)];
            System.out.println("cipherText - "+cipherText+" ctLength - "+ctLength+" plainText - "+plainText);
            int ptLength = cipher.update(cipherText, 0, ctLength, plainText,0);
            System.out.println("ptLength - "+ptLength);

            ptLength += cipher.doFinal(plainText, ptLength);

            return new String(plainText);

Console Output:

key value is : [B@b2c64
lenth is :16
byte length - 8
cipherText - [B@19125a3 ctLength - 16 plainText - [B@3e2052
Dec 17, 2014 7:09:27 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/app] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Bad arguments] with root cause
java.lang.IllegalArgumentException: Bad arguments
    at javax.crypto.Cipher.update(Cipher.java:1860)
    at com.myproject.ERA.form.model.StrongAES.decrypt_Data(StrongAES.java:38)  // this is the line - int ptLength = cipher.update(cipherText, 0, ctLength, plainText,0);
    at com.myproject.ERA.HomeController.getMethod(HomeController.java:69)
Cœur
  • 37,241
  • 25
  • 195
  • 267
Ani
  • 87
  • 10
  • You are currently not showing what you've tried and where the exception occurs. It would be great if this was [an MCVE](http://stackoverflow.com/help/mcve). – Maarten Bodewes Dec 19 '14 at 19:34

1 Answers1

0

The problem is undoubtedly the treatment of ciphertext as encoded characters, as shown by id.getBytes() in Spring / MFC. As not all byte values are valid character encodings you may lose data. In general you should define a character encoding for your plaintext and a binary encoding (such as base 64) for your ciphertext.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Hello Maarten. Sorry but i had to move from this approach. But I also thought that time there is some issue with passing the bytecode in url. I tried to encode it before passing but no luck. Just ofr the sake of knowledge, can you please tell me how should i encode the byte code and send it over url and how should i decode it when received. Thanks in advance. – Ani Dec 29 '14 at 12:07
  • The [base64url](https://tools.ietf.org/html/rfc4648#page-7) encoding is the most efficient. You can get it by encoding to normal base64 first and then replace the `/` and `+` characters as these of course have different meanings in URL's. PS a small upvote would be *very* nice in this case :) – Maarten Bodewes Dec 29 '14 at 12:27