Post

Replies

Boosts

Views

Activity

AES/GCM/NoPadding Encryption Swift iOS
Currently I have been doing AES with CBC mode encryption but as backend change in requirement we have to change to to GCM mode with random IV generation . currently I have this code :  static func encryptsData(parameters: parameters?) - (String, String) {  var jsonStr = DefaultValues.empty         do {             if let str = String(data: try JSONSerialization.data(withJSONObject: parameters ?? [:], options: .prettyPrinted), encoding: .utf8) {                 jsonStr = str             }         } catch {             debugPrint(error.localizedDescription)         }         // Get Secrete key, iv of 128 bits         let iv = [UInt8](repeating: 0, count: 16)         let randomStr = randomString(length: 16)         let key: ArrayUInt8 = Array(randomStr.utf8)         // Encrypt Request Data with Secrete Key (AES)         let aes =  try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs5)         let encrypted = try? aes.encrypt(Array(jsonStr.utf8))              if let encryptedMsg = encrypted {             let encryptedData =  Data(bytes: encryptedMsg, count: Int(encryptedMsg.count))             let encryptedBase64 = encryptedData.base64EncodedString()             //Encrypt Secrete Key using Server Public key (RSA)             let keyData = Data(bytes: key, count: key.count)             let encryptedSceKey = encryptSecKeyWithPublickKey(key: String(data: keyData, encoding: .utf8) ?? "")             return (encryptedBase64, encryptedSceKey)         }         return (DefaultValues.empty, DefaultValues.empty) }   Now , have changed the code for GCM Mode in the following lines :   let iv = AES.randomIV(AES.blockSize) //[UInt8](repeating: 0, count: 16)         var bytes = [Int8](repeating: 0, count: 16)          let randomStr = randomString(length:16)         let key: ArrayUInt8 = Array(randomStr.utf8)         // Encrypt Request Data with Secrete Key (AES)         let aes =  try! AES(key: key, blockMode: GCM(iv: iv), padding: .noPadding) else , remaining the same..But could get success through this as our encryption has to be in sync with the android/java side. On Android end this is the encryption code : lpackage com.jio.ngo.datalayer.network.encryption import android.util.Base64 import android.util.Log import com.jio.ngo.datalayer.BuildConfig import java.nio.charset.Charset import java.security.* import java.security.spec.InvalidKeySpecException import java.security.spec.X509EncodedKeySpec import javax.crypto.* import javax.crypto.spec.GCMParameterSpec import javax.crypto.spec.SecretKeySpec object Encryption { val TAG = "Encryption" private const val GCM_IV_LENGTH = 12 fun encrypt(message: String): EncryptedRequest { val encryptedRequest = EncryptedRequest() try { // 1. generate secret key using AES val keyGenerator = KeyGenerator.getInstance("AES") keyGenerator.init(256) // AES is currently available in three key sizes: 128, 192 and 256 bits.The // design and strength of all key lengths of the AES algorithm are sufficient to // protect classified information up to the SECRET level val secretKey = keyGenerator.generateKey() // 2. get string which needs to be encrypted // 3. encrypt string using secret key val raw = secretKey.encoded val skeySpec = SecretKeySpec(raw, "AES") // val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") val cipher = Cipher.getInstance("AES/GCM/NoPadding") val iv = ByteArray(GCM_IV_LENGTH) SecureRandom().nextBytes(iv) val parameterSpec = GCMParameterSpec(128, iv) //128 // val parameterSpec: GCMParameterSpec = cipher.parameters.getParameterSpec(GCMParameterSpec::class.java) // cipher.init(Cipher.ENCRYPT_MODE, skeySpec, IvParameterSpec(ByteArray(16))) cipher.init(Cipher.ENCRYPT_MODE, skeySpec, parameterSpec) val encryptedMessageBytes: ByteArray = cipher.doFinal(message.toByteArray(Charset.forName("UTF-8"))) val encrypted = ByteArray(iv.size + encryptedMessageBytes.size) System.arraycopy(iv, 0, encrypted, 0, iv.size) System.arraycopy(encryptedMessageBytes, 0, encrypted, iv.size, encryptedMessageBytes.size) val cipherTextString = Base64.encodeToString(encrypted, Base64.DEFAULT) Log.d(TAG, "cipherTextString : $cipherTextString") Log.d(TAG, "cipherTextString 1: ${Base64.encodeToString(skeySpec.encoded, Base64.DEFAULT)}") // 4. get public key val publicSpec = X509EncodedKeySpec(Base64.decode(BuildConfig.apikey, Base64.DEFAULT)) val keyFactory = KeyFactory.getInstance("RSA") val publicKey = keyFactory.generatePublic(publicSpec) // 6. encrypt secret key using public key val cipher2 = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding") cipher2.init(Cipher.ENCRYPT_MODE, publicKey) val encryptedSecretKey = Base64.encodeToString(cipher2.doFinal(secretKey.encoded), Base64.DEFAULT) //System.out.println(encryptedSecretKey); Log.d(TAG, "encryptedSecretKey : $encryptedSecretKey") // 7. pass cipherTextString (encypted sensitive data) and encryptedSecretKey to // your server via your preferred way. // Tips: // You may use JSON to combine both the strings under 1 object. // You may use a volley call to send this data to your server. encryptedRequest.encryptedText = cipherTextString encryptedRequest.encryptedSecretKeyString = encryptedSecretKey } catch (e: NoSuchAlgorithmException) { e.printStackTrace() } catch (e: InvalidKeyException) { e.printStackTrace() } catch (e: NoSuchPaddingException) { e.printStackTrace() } catch (e: IllegalBlockSizeException) { e.printStackTrace() } catch (e: BadPaddingException) { e.printStackTrace() } catch (e: InvalidKeySpecException) { e.printStackTrace() } catch (e: InvalidAlgorithmParameterException) { e.printStackTrace() } catch (e: Exception) { e.printStackTrace() } return encryptedRequest } } So, have to find way around like what Java end encryption is happening , not able to get what is the issue at our end. failing decrypting in backend when using above iOS encryption code : javax.crypto.AEADBadTagException: Tag mismatch! Please help .... Thanks !!
6
0
4.3k
Apr ’23
AES encryption with GCM Mode using crypto swift
Hi All, I have issue with doing AES encryption with GCM Mode earlier using CBC which have to change to now GCM as change in backend system, getting error "javax.crypto.AEADBadTagException: Tag mismatch!" Code have used with AES/CBC encryption is : static func encryptsData(parameters: parameters?) - (String, String) {         // Convert Parameters in Json string         var jsonStr = DefaultValues.empty         do {             if let str = String(data: try JSONSerialization.data(withJSONObject: parameters ?? [:], options: .prettyPrinted), encoding: .utf8) {                 jsonStr = str             }         } catch {             debugPrint(error.localizedDescription)         }         // Get Secrete key, iv of 128 bits         let iv = [UInt8](repeating: 0, count: 16)         let randomStr = randomString(length: 16)         let key: ArrayUInt8 = Array(randomStr.utf8)         // Encrypt Request Data with Secrete Key (AES)         let aes =  try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs5)         let encrypted = try? aes.encrypt(Array(jsonStr.utf8))         if let encryptedMsg = encrypted {             let encryptedData =  Data(bytes: encryptedMsg, count: Int(encryptedMsg.count))             let encryptedBase64 = encryptedData.base64EncodedString()             //Encrypt Secrete Key using Server Public key (RSA)             let keyData = Data(bytes: key, count: key.count)             let encryptedSceKey = encryptSecKeyWithPublickKey(key: String(data: keyData, encoding: .utf8) ?? "")             return (encryptedBase64, encryptedSceKey)         }         return (DefaultValues.empty, DefaultValues.empty)     } Please Help!! Hope have made my point Clear!! Thanks In Advance !!
3
0
4.2k
Dec ’22