5 Replies Latest reply: Oct 12, 2012 2:18 AM by sabre150 RSS

    AES SecretKeyFactory not available

    967785
      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
          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
            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
              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
                if encryption Block Size = 128
                encryption mode = CBC
                and encryption padding = PKCS7

                Then how should I proceed?
                • 5. Re: AES SecretKeyFactory not available
                  sabre150
                  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