This discussion is archived
5 Replies Latest reply: Oct 12, 2012 12:18 AM by sabre150 RSS

AES SecretKeyFactory not available

967785 Newbie
Currently Being Moderated
Hi,
I found that there is a bug in using SecretKeyFactory keyFactory with reference to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7022467

I tried implementing with KeySpec too,but found one or the other error.
I'm posting here my code.Please help me out to decrypt.

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;

public class DecryptTest {
     
     public static void main(String[] args) throws Exception {
          String keyStr = "6a6b663472346c38736873346569727538346234333534376635333962353666";
          String eid = "bf940165bcc3bca12321a5cc4c753220129337b48ad129d880f718d147a2cd1bfa79de92239ef1bc06c2f05886b0cd5d";
          String rid = "00028e7353d9c4eca480a57a1ca9ba9b";
          int keysize = 256;
          
          
          // decode the key string into bytes (using Apache Commons)
          byte[] keyBytes = Hex.decodeHex(keyStr.toCharArray());

          // create a representation of the key
          SecretKeySpec spec = new SecretKeySpec(keyBytes, "AES");

          // turn the key spec into a usable key
          SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("AES");
          SecretKey key = keyFactory.generateSecret(spec);

          // use a cipher to decrypt the eid
          Cipher cipher = Cipher.getInstance("AES");
          cipher.init(Cipher.DECRYPT_MODE, key);
          byte[] plainText = cipher.doFinal(Hex.decodeHex(eid.toCharArray())); // decode from Hex again
          
          String Eid = new String(plainText, "ASCII");
          System.out.println(Eid);
     }
}
  • 1. Re: AES SecretKeyFactory not available
    sabre150 Expert
    Currently Being Moderated
    There does seem to be a bug; you should raise a bug report. A work round is to generate the key using
            SecretKey key = new SecretKeySpec(keyBytes, "AES");
    Two points -

    1) The ciphertext in your code was not generated using the key in your code.
    2) By specifying
    Cipher cipher = Cipher.getInstance("AES");
    [
    what you actually get is
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    Now ECB block mode is generally considered insecure as it allows forgery by splicing ciphertext generated from different cleartext that decrypts to valid cleartext. It is better to use one of the feedback block modes such as CBC.
  • 2. Re: AES SecretKeyFactory not available
    967785 Newbie
    Currently Being Moderated
    well I'm new to this encryption...and the work around again gave the same error..
    import java.security.spec.KeySpec;

    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.SecretKeySpec;

    import org.apache.commons.codec.binary.Hex;

    public class DecryptTest {
         
         public static void main(String[] args) throws Exception {
              String keyStr = "6a6b663472346c38736873346569727538346234333534376635333962353666";
              String eid = "bf940165bcc3bca12321a5cc4c753220129337b48ad129d880f718d147a2cd1bfa79de92239ef1bc06c2f05886b0cd5d";
              String rid = "00028e7353d9c4eca480a57a1ca9ba9b";
              int keysize = 256;
              
              
              // decode the key string into bytes (using Apache Commons)
              byte[] keyBytes = Hex.decodeHex(keyStr.toCharArray());

              // create a representation of the key
              SecretKey spec = new SecretKeySpec(keyBytes, "AES");

              // turn the key spec into a usable key
              SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("AES");
              SecretKey key = keyFactory.generateSecret((KeySpec) spec);

              // use a cipher to decrypt the eid
              Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
              cipher.init(Cipher.DECRYPT_MODE, key);
              byte[] plainText = cipher.doFinal(Hex.decodeHex(eid.toCharArray())); // decode from Hex again
              
              String Eid = new String(plainText, "ASCII");
              System.out.println(Eid);
         }
    }

    and also I didn't get you on " The ciphertext in your code was not generated using the key in your code."
    Thanks for your help!!
  • 3. Re: AES SecretKeyFactory not available
    sabre150 Expert
    Currently Being Moderated
    964782 wrote:
    well I'm new to this encryption...and the work around again gave the same error..
    import java.security.spec.KeySpec;

    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.SecretKeySpec;

    import org.apache.commons.codec.binary.Hex;

    public class DecryptTest {
         
         public static void main(String[] args) throws Exception {
              String keyStr = "6a6b663472346c38736873346569727538346234333534376635333962353666";
              String eid = "bf940165bcc3bca12321a5cc4c753220129337b48ad129d880f718d147a2cd1bfa79de92239ef1bc06c2f05886b0cd5d";
              String rid = "00028e7353d9c4eca480a57a1ca9ba9b";
              int keysize = 256;
              
              
              // decode the key string into bytes (using Apache Commons)
              byte[] keyBytes = Hex.decodeHex(keyStr.toCharArray());

              // create a representation of the key
              SecretKey spec = new SecretKeySpec(keyBytes, "AES");

              // turn the key spec into a usable key
              SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("AES");
              SecretKey key = keyFactory.generateSecret((KeySpec) spec);

              // use a cipher to decrypt the eid
              Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
              cipher.init(Cipher.DECRYPT_MODE, key);
              byte[] plainText = cipher.doFinal(Hex.decodeHex(eid.toCharArray())); // decode from Hex again
              
              String Eid = new String(plainText, "ASCII");
              System.out.println(Eid);
         }
    }
    I obviously did not make is clear enough. You don't actually need a SecretKeyFactory; you just generate the key using
    SecretKey key = new SecretKeySpec(keyBytes, "AES");
    This way you don't need to use a SecretKeyFactory. Just use the above key to init() the Cipher.
    and also I didn't get you on " The ciphertext in your code was not generated using the key in your code."
    Thanks for your help!!
    If I apply the change I suggest I get
    javax.crypto.BadPaddingException: Given final block not properly padded
    which implies either the key is wrong or the ciphertext was not generated using the key or the block mode was different or the padding was different. For any given key bytes I can use AES in the JCE to decrypt ciphertext generated using both the BouncyCastle lightweight API and the OpenSSl library so I'm pretty sure the decryption process is correct so I think that your encryption process did not use that key or a different block mode was used or a different padding was used. Since I don't know how you generated that ciphertext I can't be more specific.
  • 4. Re: AES SecretKeyFactory not available
    967785 Newbie
    Currently Being Moderated
    if encryption Block Size = 128
    encryption mode = CBC
    and encryption padding = PKCS7

    Then how should I proceed?
  • 5. Re: AES SecretKeyFactory not available
    sabre150 Expert
    Currently Being Moderated
    964782 wrote:
    if encryption Block Size = 128
    encryption mode = CBC
    and encryption padding = PKCS7

    Then how should I proceed?
    For what you are doing PKCS7 is in effect PKCS5Padding but since you are using CBC you will need to know what the IV (initialization vector) is. A little bit of minor detective work shows that the hex decoded 'rid' is probably the bytes of the IV and then your cleartext is

    d1cd779568@mailsink.mu4.grid.brandup.net

    Edited by: sabre150 on Oct 12, 2012 8:18 AM

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points