title: Decryption AES/GCM/PKCS5Padding iOS Swift
body: <p>I am trying to decrypt a Base64Encoded String message with AES decryption.</p>
  <p><strong>Encrypted Message <em>(Base64Encoded String):</em></strong>
  tNC6umcfBS/gelbo2VJF3i4LAhUKMp4oDHWN5KyYUTWeJIQKKYx6oAcQnGncIrPJNC1tUYMKV4kJQj3q9voIOrxc1n7FmRFvDXeRgWGNcGYO66dH3VjoEgF0oxZOpfzwSZKSv3Jm7Q==</p>
  <p><strong>Password <em>(String)</em></strong> = &quot;SOMEPASSWORDSTRING&quot;</p>
  <p>Steps to Decrypt the Message:</p>
  <ol>
  <li><p>The data must be decoded from base 64 to normal string.</p>
  </li>
  <li><p>Extract the IV and the encrypted text from input</p>
  </li>
  <li><p>Use IV and the same passphrase to generate the key that was used to encrypt the text. The key generation should follow the same steps as below.</p>
  </li>
  <li><p>A PBE Secret Key is generated (256 bits)</p>
  <pre><code>    a.    Specs created with passphrase and IV as salt, 62233 as iteration count
      b.    Used PBKDF2WithHmacSHA256 to generate a secret factory because it's appropriate for turning passwords into keys.
      c.    This key is further encoded and converted to another key with AES encryption.
  </code></pre>
  </li>
  <li><p>With the generated key and IV, initialize the cipher in the exact same way as below</p>
  </li>
  <li><p>This key initializes the cipher object</p>
  <pre><code>        a.    Used AES in GCM, GCM specs are prepared using tag size of 128 bits and the IV
          b.    Cipher object is initialized using AES/GCM/PKCS5Padding.
          c.    Based on operational mode the cipher is initialized with op mode(encryption), secret key and GCM params.
  </code></pre>
  </li>
  <li><p>Generate the cipher to get the message from the encrypted text.</p>
  </li>
  </ol>
  <p>Below is the JAVA Code that is working to decrypt the input message</p>
  <pre><code>public class Decryption {
      private static final String KEY_GENERATING_ALGO = &quot;PBKDF2WithHmacSHA256&quot;;
        private static final String ENCRYPTION = &quot;AES&quot;;
        private static final String TRANSFORMATION_ALGORITHM= &quot;AES/GCM/PKCS5Padding&quot;;
         
        private static final int KEY_SIZE_BITS = 256;
        private static final int TAG_SIZE_BITS = 128;
        private static final int ITERATION_COUNT  = 62233;
        
      // Use following sample data to test the decryption-
  //tNC6umcfBS/gelbo2VJF3i4LAhUKMp4oDHWN5KyYUTWeJIQKKYx6oAcQnGncIrPJNC1tUYMKV4kJQj3q9voIOrxc1n7FmRFvDXeRgWGNcGYO66dH3VjoEgF0oxZOpfzwSZKSv3Jm7Q==
        
        // This key has is base 64 encoded with IV prepended with encrypted text
        public Cipher initCipher(int encryptMode, String password, byte[] iv) throws InvalidKeySpecException {
              try {
                  GCMParameterSpec gcmparams = new GCMParameterSpec(TAG_SIZE_BITS, iv);
                  PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), iv, ITERATION_COUNT, KEY_SIZE_BITS);
                  SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_GENERATING_ALGO);
                  SecretKey pbeKey = factory.generateSecret(pbeKeySpec);
                  byte[] keyBytes = pbeKey.getEncoded();
                  SecretKey key = new SecretKeySpec(keyBytes, ENCRYPTION);
                  Cipher cipher = Cipher.getInstance(TRANSFORMATION_ALGORITHM);
                  cipher.init(encryptMode, key, gcmparams);
                  return cipher;
              } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
                      | InvalidAlgorithmParameterException | InvalidKeySpecException ex) {
                  throw new AssertionError(ex);
              }
          }
      //Decryption Algo
          public String decrypt(String encrypted){
              byte[] decFeeder = Base64.getDecoder().decode(encrypted);
              String key = &quot;someKey&quot;; // A new key will be provided by APIF through a secure channel
              char[] password = key.toCharArray();
              try {
                  byte[] iv = Arrays.copyOfRange(decFeeder, 0, 32);
                  byte[] ciphertext = Arrays.copyOfRange(decFeeder, iv.length, decFeeder.length);
                  Cipher cipher = initCipher(Cipher.DECRYPT_MODE, key, iv);
                  byte[] message = cipher.doFinal(ciphertext);
                  String decrypted = new String(message);
                  return decrypted;
              } catch (IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException ex) {
                  throw new AssertionError(ex);
              }
          }
  } 
  </code></pre>
  <p>I used below code in Swift to generate the same as above JAVA code, but I am unable to decrypt the message/cipherText.</p>
  <pre><code> func aesDecrypt(encryptedData: Data, password: String) -&gt; Data? {
         
          let iv = Array([UInt8](encryptedData)[0 ..&lt; 33])
          let ivData = Data(iv)
          let encryptedCipher = [UInt8](encryptedData)[iv.count ..&lt; encryptedData.count]
          let encryptedCipherData = Data(encryptedCipher)
          
          let passwordKey = createKey(password:Data(password.utf8) , salt: ivData)
  
          var decryptSuccess = false
          let size = (encryptedCipher.count) + kCCBlockSizeAES128
          var clearTextData = Data.init(count: size)
          
          var numberOfBytesDecrypted : size_t = 0
          let cryptStatus = ivData.withUnsafeBytes {ivBytes in
              clearTextData.withUnsafeMutableBytes {clearTextBytes in
                  encryptedCipherData.withUnsafeBytes {encryptedBytes in
                      passwordKey.withUnsafeBytes {keyBytes in
                          CCCrypt(CCOperation(kCCDecrypt),
                                  CCAlgorithm(kCCAlgorithmAES128),
                                  CCOptions(kCCOptionPKCS7Padding),
                                  keyBytes,
                                  passwordKey.count,
                                  ivBytes,
                                  encryptedBytes,
                                  (encryptedCipher.count),
                                  clearTextBytes,
                                  size,
                                  &amp;numberOfBytesDecrypted)
                      }
                  }
              }
          }
          if cryptStatus == Int32(kCCSuccess)
          {
              clearTextData.count = numberOfBytesDecrypted
              debugPrint(clearTextData)
              decryptSuccess = true
          }
          
          
          return decryptSuccess ? clearTextData : Data.init(count: 0)
      }
  
      func createKey(password: Data, salt: Data) -&gt; Data? {
             let length = kCCKeySizeAES256
             var status = Int32(0)
             var derivedBytes = [UInt8](repeating: 0, count: length)
             password.withUnsafeBytes { (passwordBytes: UnsafePointer&lt;Int8&gt;!) in
                 salt.withUnsafeBytes { (saltBytes: UnsafePointer&lt;UInt8&gt;!) in
                     status = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),  // algorithm
                                                   passwordBytes,                // password
                                                   password.count,               // passwordLen
                                                   saltBytes,                    // salt
                                                   salt.count,                   // saltLen
                                                   UInt32(kCCPRFHmacAlgSHA256),  // prf
                                                   UInt32(62233),                // rounds
                                                   &amp;derivedBytes,                // derivedKey
                                                   length)                       // derivedKeyLen
                 }
             }
             guard status == 0 else {
                return nil
             }
             return Data(bytes: UnsafePointer&lt;UInt8&gt;(derivedBytes), count: length)
         }
  
  </code></pre>
  <p>Usage:</p>
  <pre><code> guard let encryptedData = Data(base64Encoded: input) else{
    return nil
  }
  let decryptData = aesDecrypt3(encryptedData: encryptedData)
  let decryptedMessage = String(data: decryptData, encoding: .utf8) ?? &quot;Unable to Decrypt&quot;
  </code></pre>
  <p>Any leads would be greatly appreciated, I wonder if I am missing some configuration or data conversion when trying to convert in swift.</p>