Wednesday, May 31, 2023
HomeiOS Developmentios - Producing an AES key, encrypting and decrypting with CryptoSwift would...

ios – Producing an AES key, encrypting and decrypting with CryptoSwift would not decrypt again to “Howdy World”


I am constructing a easy app, the place customers can add private diary entries within the type of textual content solely, and it will get saved to my cloud firestore database. Now, I wish to construct end-to-end encryption so the consumer’s private content material is rarely readable by anybody however them.

To realize this, I am attempting to make use of the CryptoSwift library to encrypt and decrypt content material. For testing functions, I am beginning with only a easy “Howdy World” in my ViewModel. Nevertheless, I am unable to get it to work.

Couple of questions

  • I am unable to get “Howdy world” to point out up from clear (whats up world) > encrypted > cipher > decrypted (whats up world). How can I get the identical “whats up world” outcome from my decrypt operate?

  • In what format ought to I save my key to the keychain?

  • In what format ought to I save my encrypted textual content, and iv on firebase? Ought to I proceed to make use of .toHexString() or ought to I be utilizing .toBase64()?

I am efficiently in a position to generate a key, and reserve it as a “hexString”. And I can “run” via each the encrypt and the decrypt capabilities with out errors, however they do not generate a “whats up world” from cleartext(whats up world) > encrypt > ciphertext > decrypt > helloworld.

class EncryptionService: EncryptionServicing {
    
    personal var keychainService = KeychainService()
    
    func generateKey() throws -> String  {
        print("[EncryptionService] 🔑🔑🔑 Generate key known as")
        do {
            if let userId = UserService.shared.userInfo?.userId {
                
                let userId: [UInt8] = Array(userId.utf8)
                
                // Salt added for randomness
                let salt: [UInt8] = (1...5).map( {_ in UInt8(Int.random(in: 1...10))} )

                let key = strive PKCS5.PBKDF2(
                    password: userId,
                    salt: salt,
                    iterations: 4096,
                    keyLength: 32, /* AES-256 */
                    variant: .sha2(.sha256)
                ).calculate()

                print("🔑🔑🔑 UserId: (userId)")
                print("🔑🔑🔑 Salt: (salt)")
                print("🔑🔑🔑 KEY: (key.toHexString())")

                return key.toHexString()
            }
        }
        catch {
            print(error)
        }
        return ""
    }
    
    func encrypt(clearText: String, aesKey: String) throws -> (cipherText: String, iv: String) {
        print("[EncryptionService] ✅ Encrypt known as")
        do {
            let iv = AES.randomIV(AES.blockSize)
            let keyArray = [UInt8](hex: aesKey)
            
            let aes = strive AES(key: keyArray, blockMode: CBC(iv: iv), padding: .pkcs7)
            let cipherText = strive aes.encrypt(Array(clearText.utf8))
            
            return (cipherText.toHexString(), iv.toHexString())
        }
        catch {
            print(error)
            return ("", "")
        }
    }

    func decrypt(cipherText: String, iv: String, aesKey: String) throws -> String {
        print("[EncryptionService] ✅ Decryption known as")
        do {
            print("Ciphertext: (cipherText)")
            print("Iv: (iv)")
            print("aesKey: (aesKey)")
            
            let keyArray = [UInt8](hex: aesKey)
            
            let aes = strive AES(key: keyArray, blockMode: CBC(iv: [UInt8](hex: iv)), padding: .pkcs7)
            
            print("AES Key measurement: (aes.keySize)")
            
            let decryptedText =  strive aes.decrypt(cipherText.bytes)
            
            return decryptedText.toHexString() // would not reply with "Howdy world!"
        }
    }
}

That is what my ViewModel seems like.

    @Revealed var dummyClearText: String = "Howdy World!"
    @Revealed var dummyCipherText: String = ""
    @Revealed var dummyIv: String = ""
    @Revealed var dummyDecryptedText: String = ""
    
    // Have a "encrypt" button that calls this.
    func generateCipherText() {
        do {
            let outcome = strive EncryptionService().encrypt(clearText: self.dummyClearText, aesKey: self.aesKey)
            self.dummyCipherText = outcome.cipherText
            self.dummyIv = outcome.iv
        }
        catch {
            print(error)
        }
    }
    
    // Have a "decrypt" button that calls this, and takes the generated cipher textual content as enter.
    func generateClearText() {
        do {
            let outcome = strive EncryptionService().decrypt(cipherText: self.dummyCipherText, iv: self.dummyIv, aesKey: self.aesKey)
            self.dummyDecryptedText = outcome // would not reply with "Howdy world!"
        }
        catch {
            print(error)
        }
    }```

Thanks a lot, nonetheless very a lot studying easy methods to Swift. 

Comfortable to offer extra context. 

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments