iOS Cryptokit in Java

iOS CryptoKit in Java

This is the final set of code in SWIFT:

let pass = “Password”
let data = “Text to encrypt”.data(using: .utf8)!
let key = SymmetricKey(data: SHA256.hash(data: pass.datat(using: .utf8)!))
let iv = AES.GCM.Nonce()
let mySealedBox = try AES.GCM.seal(data, using: key, nonce: iv)
dataToShare = mySealedBox.combined?.base64EncodedData()

Write this data to a file (I am using google APIs to write this data to a file on google drive)

Read this data from the file in java and pass it to the functions as defined in the question using the below code:

byte[] iv = Base64.getDecoder().decode(text.substring(0,16));
cipher[] = Base64.getDecoder().decode(text.substring(16));
byte[] key = md.digest(pass.getBytes(StandardCharsets.UTF_8));
String plainText = decrypt(cipher, key, iv);

Cross platform AES Encryption between iOS and Kotlin/Java using Apples CryptoKit

could you try this (or something like it) with your setup. From what I undestand
you need to prefix data with nonce, because data from kotlin/java contains the cipher text plus the tag at the end. CryptoKit needs nonce || ciphertext || tag.

func decrypt(data: Data) -> String {
// need to prefix data with nonce, because data from kotlin/java contains the cipher text plus the tag at the end.
// we want nonce || ciphertext || tag for CryptoKit to be happy
let combine = nonce + data
if let myNewSealedBox = try? AES.GCM.SealedBox(combined: combine),
let res = try? AES.GCM.open(myNewSealedBox, using: mykey),
let myText = try? String(decoding: res, as: UTF8.self) {
return myText
}
return ""
}

CryptoKit authenticationFailure when try decrypt

The issue probably lies within the initialisation vector or nonce you use. Counting the bytes, we come to a total of 16 nonce bytes, even though GCM only needs 12. Now, using 16 is not necessarily good or bad, but the CryptoKit implementation assumes 12 bytes when calling AES.GCM.SealedBox(combined:). In order to support 16 nonce bytes, you will have to use AES.GCM.SealedBox(nonce:ciphertext:tag:) instead.

let ciphertext = Data(...)

do {
let nonce = try AES.GCM.Nonce(data: ciphertext[0 ..< 16]
let message = ciphertext[16 ..< ciphertext.count - 16]
let tag = ciphertext[ciphertext.count - 16 ..< ciphertext.count]

let sb = try AES.GCM.SealedBox(nonce: nonce, ciphertext: ciphertext, tag: tag)
let decrypted = try AES.GCM.open(sb, using: key)
} catch {
print("Error: \(error)")
}

Looking at your server code, make sure the shared secret is not 'just' the shared secret. generateSharedSecret sounds like it's the secret after performing key exchange, but without performing the key derivation (HKDF, as seen in the Swift code).

Also looking deeper into your server code, make sure your response data contains the nonce, encrypted message and tag. Some crypto implementations force you to do this concatenation yourself. So instead of return Base64(doFinal) (pseudo code), you should instead make sure doFinal includes a tag (GCM only), and return Base64(nonce + encrypted message + tag). Again, the tag only when using GCM.

As also mentioned in the comments, GCM and CTR are different modes of operation for AES. Make sure you use the same one on both parties, so either GCM on both iOS and server or CTR on both iOS and server. Not doing so, will always result in failure of decryption.

If you want to use CTR, you'll have to take a look at CommonCrypto, the old Apple crypto library. This one has CTR implemented, but doesn't support GCM (as the implementation was never released).

One final note, when using GCM, also make sure your additional authentication data (if any) is correct.

Using iOS CryptoKit to generate key pairs not compatible with other platform

You are using two different Curves. The link you specified shows that you are trying to initiate a secp256k1 key, but that is not the same as CryptoKit P256 - which is the Curve secp256r1, notice last two chara k1 != r1. Even if private key instantiation succeeds, the public keys will differ, so signature validation (verification) will always fail.

Can you use secp256r1? It is present in the list on the site you linked to, above sect571r1.

Do you have to use secp256k1? If so you can use

https://github.com/Sajjon/K1

Want to use secp256k1 in CryptoKit in the future? Help me upvote my proposal to get it added to swift-crypto (open source variant of CryptoKit)!

Swift CryptoKit AES Encryption and Javascript AES Decryption

CryptoJS uses CBC mode by default, and doesn’t support GCM at all. You shouldn’t use CryptoJS at the best of times (the native and better-designed Web Crypto API is to be preferred), but especially not on the server, where Node.js has always had a native crypto module.

First, include the GCM nonce and tag, which are essential components:

return val.combined!.base64EncodedString()

Then, in Node.js, using the layout as described in the documentation for the combined property:

The data layout of the combined representation is: nonce, ciphertext, then tag.

// where `sealedBox` is a buffer obtained with `Buffer.from(encryptedString, 'base64')`
let nonce = sealedBox.slice(0, 12);
let ciphertext = sealedBox.slice(12, -16);
let tag = sealedBox.slice(-16);
let decipher = crypto.createDecipheriv('aes-128-gcm', key, nonce);
decipher.setAuthTag(tag);
let decrypted =
Buffer.concat([decipher.update(ciphertext), decipher.final()])
.toString('utf8');

Once that’s working, don’t forget to fix your key, because .init(data: Array(key.utf8)) is very uncomfortable (your AES keys should not be valid UTF-8).

  • If you’re starting with a password (for a good reason, not just because it seemed convenient), use a PBKDF to get key bytes. (Unfortunately, no PBKDF implementations are built into CryptoKit.)

    … but if the good reason is that it’s a user-provided password and you’re claiming to provide security, please get someone experienced with use of cryptography to review your work.

  • Otherwise, generate a random key safely and decode it from a Base64 or hex string. No UTF-8.

    node -p 'crypto.randomBytes(16).toString("base64")'

    And get someone experienced with use of cryptography to review your work anyway.



Related Topics



Leave a reply



Submit