How to decrypt Swift CryptoKit chacha20-poly1305 cipher in JavaScript?

1.2k views Asked by At

I encrypted a string in swift using CryptoKit's ChaChaPoly:

// Swift

let txt: Data? = "secret message".data(using: .utf8)
let key = SymmetricKey(data: SHA256.hash(data: "password".data(using: .utf8)!))

let sealedBoxData = try! ChaChaPoly.seal(txt!, using: key).combined

//return F6u88lkmmz8RrjvfJ22r4vrKmWuY8a2DNpjUKZVUi9Wp9QjZVgheBihn
sealedBoxData.base64EncodedString() 

//return F6u88lkmmz8Rrjvf
sealedBox.nonce.withUnsafeBytes { return Data(Array($0)).base64EncodedString() } 

//return J22r4vrKmWuY8a2DNpg=
sealedBox.ciphertext.withUnsafeBytes { return Data(Array($0)).base64EncodedString() }

//return 1CmVVIvVqfUI2VYIXgYoZw==
sealedBox.tag.withUnsafeBytes { return Data(Array($0)).base64EncodedString() } 

Now I have trouble porting the encrypt and decrypt functions to Javascript.

// Swift

// decrypting.. 
let ss = Data(base64Encoded: sealedBoxData.base64EncodedString(), options: .ignoreUnknownCharacters)

// how to extract tag and cipher in javascript like this?
let box = try! ChaChaPoly.SealedBox(combined: ss!)
box.tag.withUnsafeBytes { return Data(Array($0)).base64EncodedString() } 

let result = try! ChaChaPoly.open(box, using: key)

// return "secret message"
let txt = String(data: result, encoding: String.Encoding.utf8)


Based on the sealedBoxData's base64 String, I'm able to extract the IV (nonce) and part of the cipher text.

// React JS

function decrypt(b64SealedBoxData, key) {

  // able to parse correct value
  var iv = b64SealedBoxData.substring(0, 16)

  // last few characters parsed is incorrect
  var cipher = b64SealedBoxData.substring(16) 

  // unable to derive from sealboxdata string
  var tag = null 
}

The base64 ciphertext obtained from CryptoKit's sealedBox.ciphertext gave me J22r4vrKmWuY8a2DNpg=, but the sealedBoxData base64 string only contains J22r4vrKmWuY8a2DNp. I don't know how sealedBox.tag got transform into the final sealedBox b64 String.

How can I extract the proper ciphertext and tag in Javascript? How can I encrypt the text using JS in a way that swift's chachapoly function is able to decrypt it?


I tried to use this JS library to encrypt and decrypt chacha20poly1305 cipher, but I can't get a working example from it. :(

This stackoverflow question is quite similar to what I'm facing, except I'm using chachaPoly and JS.

Thank you for your time. :)

0

There are 0 answers