In Java/Android we have used
private const val secretKey = "1f23456d2d014be5" private const val salt = "a986e0093328765e" private const val ivKey = "9898989890KJHYTR" fun passwordEncryptMethod(stringToEncrypt: String): String? { var encryptedText = "" try { val iv: ByteArray = ivKey.toByteArray() val ivspec = IvParameterSpec(iv) val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256") val spec: KeySpec = PBEKeySpec( secretKey.toCharArray(), salt.toByteArray(), 65536, 256 ) val tmp = factory.generateSecret(spec) val secretKey = SecretKeySpec(tmp.encoded, "AES") val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec) val encryptedByte: ByteArray = cipher.doFinal(stringToEncrypt.toByteArray(charset("UTF-8"))) encryptedText = Base64.encodeToString(encryptedByte, Base64.NO_WRAP) return encryptedText } catch (e: Exception) { Log.i("Error encrypting:", e.message ?: "") } return encryptedText } In iOS Swift I have used . https://gist.github.com/hfossli/7165dc023a10046e2322b0ce74c596f8
Approach 1 using CCKeyDerivationPBKDF & CCCrypt
let digest = "StringToEncrypt".data(using: .utf8)! let password = "1f23456d2d014be5".data(using: .utf8)! let salt = "a986e0093328765e".data(using: String.Encoding.utf8)!//AES256.randomSalt() let iv = "9898989890KJHYTR".data(using: String.Encoding.utf8)!//AES256.randomIv() let key = try AES256.createKey(password: digest, salt: salt) var aes = try AES256(key: key, iv: iv) let encrypted = try aes.encrypt(password) print( #function, (encrypted.base64EncodedString())) //Helper function
static func createKey(password: Data, salt: Data) throws -> Data { let length = kCCKeySizeAES256 var status = Int32(0) var derivedBytes = [UInt8](repeating: 0, count: length) password.withUnsafeBytes { (passwordBytes: UnsafePointer<Int8>!) in salt.withUnsafeBytes { (saltBytes: UnsafePointer<UInt8>!) in status = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), // algorithm passwordBytes, // password password.count, // passwordLen saltBytes, // salt salt.count, // saltLen CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256), // prf 65536, // rounds &derivedBytes, // derivedKey length) // derivedKeyLen } } guard status == 0 else { throw Error.keyGeneration(status: Int(status)) } return Data(bytes: UnsafePointer<UInt8>(derivedBytes), count: length) } mutating func encrypt(_ digest: Data) throws -> Data { return try crypt(input: digest, operation: CCOperation(kCCEncrypt)) } mutating func decrypt(_ encrypted: Data) throws -> Data { return try crypt(input: encrypted, operation: CCOperation(kCCDecrypt)) } private mutating func crypt(input: Data, operation: CCOperation) throws -> Data { var outLength = Int(0) var outBytes = [UInt8](repeating: 0, count: input.count + kCCBlockSizeAES128) // var status: CCCryptorStatus = CCCryptorStatus(kCCSuccess) var keyValue = self.key let status: CCCryptorStatus = input.withUnsafeBytes {encryptedBytes in iv.withUnsafeBytes {ivBytes in keyValue.withUnsafeMutableBytes {keyBytes in CCCrypt( // Stateless, one-shot encrypt operation CCOperation(kCCEncrypt), // op: CCOperation CCAlgorithm(kCCAlgorithmAES), // alg: CCAlgorithm CCOptions(kCCOptionPKCS7Padding), // options: CCOptions keyBytes.baseAddress, // key: the "password" key.count, // keyLength: the "password" size ivBytes.baseAddress, // iv: Initialization Vector encryptedBytes.baseAddress, // dataIn: Data to encrypt bytes input.count, // dataInLength: Data to encrypt size &outBytes, //bufferBytes.baseAddress! + kCCBlockSizeAES128, // dataOut: encrypted Data buffer outBytes.count, // dataOutAvailable: encrypted Data buffer size &outLength // dataOutMoved: the number of bytes written ) } } } guard status == kCCSuccess else { throw Error.cryptoFailed(status: status) } return Data(bytes: UnsafePointer<UInt8>(outBytes), count: outLength) } Approach 2 Based on this link How to use CommonCrypto for PBKDF2 in Swift 2 & 3
But I am getting different base64 encoded string in both platform. Please help.
secretKeyin swiftsecretKeyin the Android code is the password, seePBEKeySpec(), which should thus correspond to the second parameterpasswordin the Swift code.stringToEncryptin Android is the password where it passing to cipher &secretKeypassing intoPBEKeySpecwhich is prerequisite forCipher for android.