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.
secretKey
in swift – CheerfulsecretKey
in the Android code is the password, seePBEKeySpec()
, which should thus correspond to the second parameterpassword
in the Swift code. – ConclusivestringToEncrypt
in Android is the password where it passing to cipher &secretKey
passing intoPBEKeySpec
which is prerequisite forCipher for android.
– Cheerful