javaswiftcryptographyaes-gcmcryptoswift

AES GCM key derivation swift


I'm trying to implement in swift the equivalent of my code in java. Basically is an AES implementation with GCM padding and I'm using a key derivation for that. In swift I'm using the CryptoSwift library.

My issue is that I cannot get the same encrypted text in swift. After a very long research I couldn't find any solutions for my problem, I even saw the test code of the CryptoSwift library repository to get any ideas but with no luck

This is my java code:

GCMParameterSpec ivParameterSpec = new GCMParameterSpec(128, "ivVector".getBytes());
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec("myPassword".toCharArray(), "salt".getBytes(), 1000, 256);
SecretKey tmp = secretKeyFactory.generateSecret(keySpec);
key = new SecretKeySpec(tmp.getEncoded(), "AES");
encryptCipher = Cipher.getInstance("AES/GCM/NoPadding");

encryptCipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
            byte[] encryptedWord = Base64.encode(encryptCipher.doFinal("example".getBytes("UTF-8")));

And this is my swift code:

do{
    keyDerivation = try PKCS5.PBKDF2(password: "myPassword".bytes, salt: "salt".bytes, iterations: 1000, keyLength: 32, variant: .sha1).calculate()
    let gcm = GCM(iv: keyDerivation, mode: .combined)
    let aes = try AES(key: keyDerivation, blockMode: gcm, padding: .noPadding)
    let encryptedText = try aes.encrypt("example".bytes)

}catch{
    print(error)
}

Any help would be appreciated.


Solution

  • Your IV doesn't match in both cases. In Java you use a string, and in Swift you use the derived key in keyDerivation.

    Furthermore, you should make sure that you use the same character encoding. I'd not use getBytes or similar for either language. Explicitly specifying UTF-8 is probably best.

    Note that the Java PBKDF2WithHmacSHA1 may handle password encoding in a rather peculiar way, so some kind of input validation on the password is probably in order.

    Needless to say, the salt should be random for each call to encrypt, not static. I presume this is just test code though.