views:

182

answers:

2

I have generated on my android application a pair of RSA Keys.

I receive from a web service - an AES Key, encrypted with my RSA public key - a String encoded with the AES key.

So I must do the following: - decrypt the AES Key - decrypt the string with the obtained AES Key.

To generate the RSA Keys I did:

 keyGen = KeyPairGenerator.getInstance("RSA");
  keyGen.initialize(size);
  keypair = keyGen.genKeyPair();
  privateKey = keypair.getPrivate();
  publicKey = keypair.getPublic();

On RSA decrypt I use :

public static byte[] decryptRSA( PrivateKey key, byte[] text) throws Exception
      { 
          byte[] dectyptedText = null;

          Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
          cipher.init(Cipher.DECRYPT_MODE, key);
          dectyptedText = cipher.doFinal(text);
          return dectyptedText;
      }

On AES decrypt I use:

public static byte[] decryptAES(byte[] key, byte[] text) throws Exception {   
            SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");   
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS1Padding");   
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);   
            byte[] decrypted = cipher.doFinal(text);   
            return decrypted;   
        }

So, in my code, to obtain the decrypted AES Key I do

byte[] decryptedAESKey = sm.decryptRSA(key, Base64.decode(ReceivedBase64EncryptedAESKey));
byte[] decryptedString = sm.decryptAES(decryptedAESKey, Base64.decode(ReceivedEncryptedAESString));

On the end I get a null for decryptedString. What am I doing wrong ?

A: 

I'm not sure what language or libraries you are using (looks like Java?), but some really general things to try:

  1. Did you get the encrypted string, ok? Check the length of ReceivedEncryptedAESString and the output of the Base64.decode to check they look alright.
  2. AES decryption can't fail so it must be a problem in the library initialisation. Check the value/state of cipher after the construction step and the init step.
  3. Try a simpler testcase: ignore the RSA encryption and just try to decrypt something using your Cipher object.
Amoss
I am using Android with its included libraries. 1. looks allright, for instance I get the ReceivedEncryptedAESString= qjYcPCHkFpbTjntDCpXCGabSY5DFH... and the decryptedAESKey looks like:[121, 98, 51, 100, 108, 112, 118, 107, 118, 97]
Alin
2. the problem appears to be on cipher.init(Cipher.DECRYPT_MODE, skeySpec); as it throws an exception: InvalidKeyException: Key length not 128/192/256 bits. Maybe I do RSA decryption wrong ?
Alin
How long is the key array? It is possible that it too short (less than 128 bits) and needs some kind of padding, or that it is too long and needs truncating. AES is only defined on those three key-lengths. As this is a string that you've retrieved from the web-service you need to find out why it is the wrong length. Maybe the message from the web-service is truncated?
Amoss
+1  A: 

Well, the thing is that the key decrypted was 8 byte long and I had to make it 16 byte to be AES 128 bits compatible

So, I made a method to convert it back

 private static byte[] GetKey(byte[] suggestedKey)
      {
          byte[] kRaw = suggestedKey;
          ArrayList<Byte> kList = new  ArrayList<Byte>();

          for (int i = 0; i < 128; i += 8)
          {
              kList.add(kRaw[(i / 8) % kRaw.length]);
          }

          byte[] byteArray = new byte[kList.size()];
          for(int i = 0; i<kList.size(); i++){
            byteArray[i] = kList.get(i);
          }
          return byteArray;
      }

And the rewritten decrypt method:

  public static byte[] decryptAES(byte[] key, byte[] text) throws Exception {   

          SecretKeySpec skeySpec = new SecretKeySpec(GetKey(key), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");  

            byte [] iv = new byte[cipher.getBlockSize()];
            for(int i=0;i<iv.length;i++)iv[i] = 0;
            IvParameterSpec ivSpec = new IvParameterSpec(iv);
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);

            byte[] decrypted = cipher.doFinal(text);   
            return decrypted;   
        }
Alin