### Full AES Encryption/Decryption Workflow Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md A comprehensive example showing key derivation using PBKDF2, random IV generation, AES encryption, and decryption. Assumes PKCS7 padding. ```swift let password: [UInt8] = Array("s33krit".utf8) let salt: [UInt8] = Array("nacllcan".utf8) /* Generate a key from a `password`. Optional if you already have a key */ let key = try PKCS5.PBKDF2( password: password, salt: salt, iterations: 4096, keyLength: 32, /* AES-256 */ variant: .sha2(.sha256) ).calculate() /* Generate random IV value. IV is public value. Either need to generate, or get it from elsewhere */ let iv = AES.randomIV(AES.blockSize) /* AES cryptor instance */ let aes = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) /* Encrypt Data */ let inputData = Data() let encryptedBytes = try aes.encrypt(inputData.byteArray) let encryptedData = Data(encryptedBytes) /* Decrypt Data */ let decryptedBytes = try aes.decrypt(encryptedData.byteArray) let decryptedData = Data(decryptedBytes) ``` -------------------------------- ### Base64 Encoding and Decoding Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Provides examples for decoding Base64 strings to data and encoding bytes to Base64 strings. ```swift "aPf/i9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=".decryptBase64ToString(cipher) ``` ```swift "aPf/i9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=".decryptBase64(cipher) ``` ```swift bytes.toBase64() ``` -------------------------------- ### Derive Key using HKDF Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Example of deriving a key using the HMAC-based Key Derivation Function (HKDF) with SHA-256. ```swift let password: Array = Array("s33krit".utf8) let salt: Array = Array("nacllcan".utf8) let key = try HKDF(password: password, salt: salt, variant: .sha2(.sha256)).calculate() ``` -------------------------------- ### Encrypt and Decrypt with Blowfish Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Example of encrypting and decrypting data using the Blowfish cipher in CBC mode with PKCS7 padding. Requires a key and an IV. ```swift let encrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(message) let decrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted) ``` -------------------------------- ### Derive Key using Scrypt Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates key derivation using the Scrypt algorithm. Note that the 'p' parameter increases work time even on multicore systems as Scrypt implementation does not parallelize work. ```swift let password: Array = Array("s33krit".utf8) let salt: Array = Array("nacllcan".utf8) // Scrypt implementation does not implement work parallelization, so `p` parameter will // increase the work time even in multicore systems let key = try Scrypt(password: password, salt: salt, dkLen: 64, N: 16384, r: 8, p: 1).calculate() ``` -------------------------------- ### Apply PKCS7 Padding Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Shows how to add PKCS7 padding to input data for algorithms that require block-aligned input. ```swift let input = Array("hello".utf8) let padded = Padding.pkcs7.add(to: input, blockSize: AES.blockSize) ``` -------------------------------- ### AES-256 Encryption Initialization Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Illustrates initializing an AES cipher instance with a 32-byte key for AES-256, a 16-byte IV for CBC mode, and PKCS7 padding. ```swift let aes = try AES(key: [1,2,3 /* ... 32 bytes total */], blockMode: CBC(iv: [1,2,3 /* ... 16 bytes total */]), padding: .pkcs7) let encryptedBytes = try aes.encrypt(Array("secret message".utf8)) ``` -------------------------------- ### Initialize RSA from Parameters Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Initialize an RSA object with existing modulus (n), public exponent (e), and private exponent (d). Ensure these parameters are correctly formatted byte arrays. ```swift let input: Array = [0,1,2,3,4,5,6,7,8,9] let n: Array = [] // RSA modulus let e: Array = [] // RSA public exponent let d: Array = [] // RSA private exponent let rsa = RSA(n: n, e: e, d: d) do { let encrypted = try rsa.encrypt(input) let decrypted = try rsa.decrypt(encrypted) } catch { print(error) } ``` -------------------------------- ### Derive Key using PKCS5 PBKDF2 Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Shows how to derive a cryptographic key from a password and salt using the PBKDF2 algorithm with SHA-256. Specify iterations and key length. ```swift let password: Array = Array("s33krit".utf8) let salt: Array = Array("nacllcan".utf8) let key = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 4096, keyLength: 32, variant: .sha2(.sha256)).calculate() ``` -------------------------------- ### RSA Key Generation, Encryption, Decryption, Signing, and Verification Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Demonstrates RSA key generation, import/export of keys, PKCS#1 v1.5 encryption/decryption, and EMSA-PKCS1-v1_5 signing/verification. Keys can be imported/exported as DER-encoded Data. ```swift import CryptoSwift // Key generation let privateKey = try RSA(keySize: 2048) print(privateKey) // "CryptoSwift.RSA.PrivateKey<2048>" // Export and import keys let publicKeyData = try privateKey.publicKeyExternalRepresentation() // Data (DER) let privateKeyData = try privateKey.externalRepresentation() // Data (DER) let importedPub = try RSA(rawRepresentation: publicKeyData) let importedPriv = try RSA(rawRepresentation: privateKeyData) // Encryption / Decryption (PKCS#1 v1.5 by default) let message: [UInt8] = Array("Hello RSA".utf8) let ciphertext = try importedPub.encrypt(message) let plaintext = try privateKey.decrypt(ciphertext) print(String(bytes: plaintext, encoding: .utf8)!) // "Hello RSA" // Signing and verification let signature = try privateKey.sign(message, variant: .message_pkcs1v15_SHA256) let valid = try importedPub.verify(signature: signature, for: message, variant: .message_pkcs1v15_SHA256) print(valid) // true // Raw init from existing parameters (n, e, d as byte arrays) let n: [UInt8] = [/* modulus bytes */] let e: [UInt8] = [0x01, 0x00, 0x01] // 65537 let d: [UInt8] = [/* private exponent bytes */] let rsa = RSA(n: n, e: e, d: d) ``` -------------------------------- ### Calculate Message Authentication Code (MAC) Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates calculating MACs using Poly1305, HMAC-SHA256, and CMAC. Requires a key and message. ```swift let key = Array(repeating: 0x01, count: 32) let message = Array("authenticated message".utf8) let poly1305 = try Poly1305(key: key).authenticate(message) let hmac = try HMAC(key: key, variant: .sha2(.sha256)).authenticate(message) let cmac = try CMAC(key: key).authenticate(message) ``` -------------------------------- ### Import CryptoSwift Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Import the CryptoSwift library to access its functionalities. This is a prerequisite for all CryptoSwift operations. ```swift import CryptoSwift ``` -------------------------------- ### RSA Signature and Verification Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Illustrates how to create a digital signature for a message using a private key and verify its authenticity using the corresponding public key. This ensures message integrity and sender authenticity. ```swift // Alice Generates a Private Key let alicesPrivateKey = try RSA(keySize: 2048) // Alice wants to sign a message that she agrees with let messageAliceSupports = "Hi my name is Alice!" let alicesSignature = try alicesPrivateKey.sign(messageAliceSupports.bytes) // Alice shares her Public key and the signature with Bob let alicesPublicKeyData = try alicesPrivateKey.publicKeyExternalRepresentation() // Bob receives the raw external representation of Alice's public key and imports it! let bobsImportOfAlicesPublicKey = try RSA(rawRepresentation: alicesPublicKeyData) // Bob can now verify that Alice signed the message using the Private key associated with her shared Public key. let verifiedSignature = try bobsImportOfAlicesPublicKey.verify(signature: alicesSignature, for: "Hi my name is Alice!".bytes) if verifiedSignature == true { // Bob knows that the signature Alice provided is valid for the message and was signed using the Private key associated with Alice's shared Public key. } else { // The signature was invalid, so either // - the message Alice signed was different than what we expected. // - or Alice used a Private key that isn't associated with the shared Public key that Bob has. } ``` -------------------------------- ### Calculate SHA Digests Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Shows how to compute SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 digests for `Data` objects. ```swift let data = Data([0x01, 0x02, 0x03]) let sha1Digest = data.sha1() let sha224Digest = data.sha224() let sha256Digest = data.sha256() let sha384Digest = data.sha384() let sha512Digest = data.sha512() ``` -------------------------------- ### Encrypt and Decrypt with Rabbit Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates encryption and decryption using the Rabbit stream cipher. Requires a key and an IV. ```swift let encrypted = try Rabbit(key: key, iv: iv).encrypt(message) let decrypted = try Rabbit(key: key, iv: iv).decrypt(encrypted) ``` -------------------------------- ### Convert Data to Array of Bytes Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates converting a `Data` object to an `Array` using the `byteArray` property. ```swift let data = Data([0x01, 0x02, 0x03]) ``` ```swift let bytes = data.byteArray // [1,2,3] ``` -------------------------------- ### Hexadecimal Encoding and Decoding Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Shows how to convert between hexadecimal strings and `Array` using `Array(hex:)` and `toHexString()`. ```swift let bytes = Array(hex: "0x010203") // [1,2,3] ``` ```swift let hex = bytes.toHexString() // "010203" ``` -------------------------------- ### AES CBC Encryption and Decryption with PKCS7 Padding Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates AES encryption and decryption using CBC mode with PKCS7 padding. Ensure the key is of the correct length and the IV is randomly generated for CBC mode. ```swift let input: Array = [0,1,2,3,4,5,6,7,8,9] let key: Array = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] let iv: Array = [] // Random bytes of `AES.blockSize` length do { let encrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(input) let decrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted) } catch { print(error) } ``` -------------------------------- ### Digest - Hash Functions Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Provides static methods for MD5, SHA-1, SHA-2, and SHA-3 digest calculations. Convenience instance methods are available on Array, Data, and String. ```APIDOC ## Digest - Hash Functions ### Description Provides static methods for MD5, SHA-1, SHA-2 (224/256/384/512), and SHA-3 digest calculation. Convenience instance methods are available on `Array`, `Data`, and `String`. ### Usage #### Static API on Digest ```swift import CryptoSwift let md5Bytes = Digest.md5([0x01, 0x02, 0x03]) let sha256Bytes = Digest.sha256([0x01, 0x02, 0x03]) let sha3Bytes = Digest.sha3([0x01, 0x02, 0x03], variant: .sha256) ``` #### Array Extensions ```swift let input: [UInt8] = Array("hello world".utf8) print(input.md5().toHexString()) print(input.sha256().toHexString()) print(input.sha3(.sha512).toHexString()) ``` #### Data Extensions ```swift let data = Data([0x01, 0x02, 0x03]) let sha1Data: Data = data.sha1() let sha512Data: Data = data.sha512() ``` #### String Extensions ```swift let hexDigest: String = "hello".md5() let sha256Hex: String = "hello".sha256() let sha3Hex: String = "hello".sha3(.sha256) ``` #### Incremental / Streaming SHA-2 ```swift var digest = MD5() _ = try digest.update(withBytes: Array("hello ".utf8)) _ = try digest.update(withBytes: Array("world".utf8)) let result = try digest.finish() print(result.toHexString()) ``` ``` -------------------------------- ### Build CryptoSwift XCFramework Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Build the CryptoSwift.xcframework locally for manual Xcode integration. This is an alternative to Swift Package Manager. ```sh ./scripts/build-framework.sh ``` -------------------------------- ### RSA Encryption and Decryption Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates the process of encrypting a message using a public key and decrypting it with the corresponding private key. This is fundamental for secure communication. ```swift // Alice Generates a Private Key let alicesPrivateKey = try RSA(keySize: 2048) // Alice shares her **public** key with Bob let alicesPublicKeyData = try alicesPrivateKey.publicKeyExternalRepresentation() // Bob receives the raw external representation of Alice's public key and imports it let bobsImportOfAlicesPublicKey = try RSA(rawRepresentation: alicesPublicKeyData) // Bob can now encrypt a message for Alice using her public key let message = "Hi Alice! This is Bob!" let privateMessage = try bobsImportOfAlicesPublicKey.encrypt(message.bytes) // This results in some encrypted output like this // URcRwG6LfH63zOQf2w+HIllPri9Rb6hFlXbi/bh03zPl2MIIiSTjbAPqbVFmoF3RmDzFjIarIS7ZpT57a1F+OFOJjx50WYlng7dioKFS/rsuGHYnMn4csjCRF6TAqvRQcRnBueeINRRA8SLaLHX6sZuQkjIE5AoHJwgavmiv8PY= // Bob can now send this encrypted message to Alice without worrying about people being able to read the original contents // Alice receives the encrypted message and uses her private key to decrypt the data and recover the original message let originalDecryptedMessage = try alicesPrivateKey.decrypt(privateMessage) print(String(data: Data(originalDecryptedMessage), encoding: .utf8)) // "Hi Alice! This is Bob!" ``` -------------------------------- ### Hashing, Encryption, and Authentication on Strings Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Calculate SHA-256 hash, encrypt strings to hex or Base64, and compute HMAC digests directly on String objects. Ensure the cipher and HMAC variant are correctly initialized. ```swift // Digest, encrypt, authenticate on String let hash = "hello".sha256() // hex string let encStr = try "hello world 1234".encrypt(cipher: cipher) // hex string of ciphertext let b64enc = try "hello world 1234".encryptToBase64(cipher: cipher) let mac = try "message".authenticate(with: HMAC(key: Array("key".utf8), variant: .sha2(.sha256))) ``` -------------------------------- ### ChaCha20 Encryption and Decryption using Convenience Extensions Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Utilizes convenience extensions for ChaCha20 encryption and decryption. This method simplifies the process by providing direct encrypt/decrypt methods on Data objects. ```swift let plain = Data([0x01, 0x02, 0x03]) let encrypted = try! plain.encrypt(ChaCha20(key: key, iv: iv)) let decrypted = try! encrypted.decrypt(ChaCha20(key: key, iv: iv)) ``` -------------------------------- ### Calculate MD5 Digest Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates calculating the MD5 hash for an array of bytes or `Data` objects. Supports direct calculation or incremental updates. ```swift let input: Array = [0x01, 0x02, 0x03] let md5Digest = input.md5() let md5Digest2 = Digest.md5(input) ``` ```swift let data = Data([0x01, 0x02, 0x03]) let md5Digest = data.md5() ``` ```swift let hash = "123".md5() // "123".bytes.md5() ``` ```swift do { var digest = MD5() _ = try digest.update(withBytes: [0x31, 0x32]) _ = try digest.update(withBytes: [0x33]) let result = try digest.finish() } catch { print(error) } ``` -------------------------------- ### CryptoSwift File Header Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/CONTRIBUTING.md Use this header for all new files added to the CryptoSwift project. It includes copyright information and licensing terms. ```objective-c // // CryptoSwift // // Copyright (C) Marcin Krzyżanowski // This software is provided 'as-is', without any express or implied warranty. // // In no event will the authors be held liable for any damages arising from the use of this software. // // Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: // // - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required. // - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. // - This notice may not be removed or altered from any source or binary distribution. // ``` -------------------------------- ### Calculate CRC Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates calculating CRC16 and CRC32 checksums for both `Array` and `Data` objects. ```swift let bytes: Array = [0x01, 0x02, 0x03] let data = Data(bytes) let bytesCRC16 = bytes.crc16() let dataCRC16 = data.crc16() let bytesCRC32 = bytes.crc32() let dataCRC32 = data.crc32() ``` -------------------------------- ### HMAC Authentication with Various Hash Variants Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Implements HMAC (RFC 2104) with support for MD5, SHA-1, SHA-2, and SHA-3. The recommended variant is .sha2(.sha256). Provides byte-array, Array, Data, and String extensions for authentication. ```swift import CryptoSwift let key: [UInt8] = Array("supersecretkey".utf8) let message: [UInt8] = Array("authenticated message".utf8) // Byte-array API let mac = try HMAC(key: key, variant: .sha2(.sha256)).authenticate(message) print(mac.toHexString()) // SHA-3 variant let mac3 = try HMAC(key: key, variant: .sha3(.sha256)).authenticate(message) // Array extension shortcut let mac2 = try message.authenticate(with: HMAC(key: key, variant: .sha2(.sha512))) // Data extension let dataMsg = Data(message) let macData = try dataMsg.authenticate(with: HMAC(key: key, variant: .sha2(.sha256))) // String extension — returns hex string let hexMAC = try "hello".authenticate(with: HMAC(key: key, variant: .sha2(.sha256))) ``` -------------------------------- ### Add CryptoSwift Dependency (Carthage) Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Specify CryptoSwift in your Cartfile for use with Carthage. Carthage builds the framework and you drag it into your Xcode project. ```ruby github "krzyzanowskim/CryptoSwift" ``` -------------------------------- ### AES Incremental Encryption Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates incremental encryption using AES. This method is suitable for large data where memory is a concern, allowing data to be processed in chunks. ```swift do { var encryptor = try AES(key: "keykeykeykeykeyk", iv: "drowssapdrowssap").makeEncryptor() var ciphertext = Array() // aggregate partial results ciphertext += try encryptor.update(withBytes: Array("Nullam quis risus ".utf8)) ciphertext += try encryptor.update(withBytes: Array("eget urna mollis ".utf8)) ciphertext += try encryptor.update(withBytes: Array("ornare vel eu leo.".utf8)) // finish at the end ciphertext += try encryptor.finish() print(ciphertext.toHexString()) } catch { print(error) } ``` -------------------------------- ### Hex Encoding and Decoding with CryptoSwift Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Use the `hex` initializer for Array and Data to decode hex strings. The `toHexString()` method converts byte arrays and Data objects back to hex strings. Prefixes like '0x' are optional. ```swift import CryptoSwift // Hex encoding / decoding let bytes: [UInt8] = Array(hex: "0x010203") // [1, 2, 3] let bytes2:[UInt8] = Array(hex: "deadbeef") // no prefix also works let hex = bytes.toHexString() // "010203" let data = Data(hex: "deadbeef") let hexBack = data.toHexString() // "deadbeef" let byteArray: [UInt8] = data.byteArray // [0xde, 0xad, 0xbe, 0xef] ``` -------------------------------- ### String to Bytes and Base64 Conversion Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Convert strings to their UTF-8 byte representation using the `.bytes` property and encode byte arrays to Base64 strings with `.toBase64()`. Decode Base64 strings back into Data. ```swift // String to bytes and back let strBytes: [UInt8] = "hello world".bytes // UTF-8 bytes let b64 = strBytes.toBase64() // Base64 string let fromB64 = Data(base64Encoded: b64!)!.byteArray ``` -------------------------------- ### AES Encrypt All at Once Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Encrypts a string using AES-128 with CBC mode and PKCS7 padding in a single operation. Handles potential errors using do-catch. ```swift do { let aes = try AES(key: "keykeykeykeykeyk", iv: "drowssapdrowssap") // aes128 let ciphertext = try aes.encrypt(Array("Nullam quis risus eget urna mollis ornare vel eu leo.".utf8)) } catch { } ``` -------------------------------- ### Add CryptoSwift as Git Submodule Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Vendor CryptoSwift directly into an Xcode project by adding it as a Git submodule. ```sh git submodule add https://github.com/krzyzanowskim/CryptoSwift.git ``` -------------------------------- ### Blowfish Block Cipher Encryption and Decryption Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Demonstrates the use of the Blowfish block cipher with CBC mode and PKCS7 padding. Note that Blowfish is recommended only for compatibility with existing systems. ```swift import CryptoSwift let key: [UInt8] = Array("blowfishkey".utf8) // 4–56 bytes let iv: [UInt8] = Array(repeating: 0x00, count: Blowfish.blockSize) // 8 bytes let bf = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) let enc = try bf.encrypt(Array("hello blowfish".utf8)) let dec = try bf.decrypt(enc) print(String(bytes: dec, encoding: .utf8)!) // "hello blowfish" ``` -------------------------------- ### Rabbit Stream Cipher Encryption and Decryption Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Shows how to use the Rabbit stream cipher with a 16-byte key and an optional 8-byte IV. Encryption and decryption are demonstrated, including a variant without an IV. ```swift import CryptoSwift let key: [UInt8] = Array(repeating: 0x00, count: Rabbit.keySize) // 16 bytes let iv: [UInt8] = Array(repeating: 0x01, count: Rabbit.ivSize) // 8 bytes let rabbit = try Rabbit(key: key, iv: iv) let enc = try rabbit.encrypt(Array("rabbit cipher".utf8)) let dec = try Rabbit(key: key, iv: iv).decrypt(enc) print(String(bytes: dec, encoding: .utf8)!) // "rabbit cipher" // Without IV let rabbitNoIV = try Rabbit(key: key) let enc2 = try rabbitNoIV.encrypt(Array("no iv".utf8)) ``` -------------------------------- ### Encrypt and Decrypt with ChaCha20 Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Basic encryption and decryption using the ChaCha20 stream cipher. Requires a key and an initialization vector (IV). ```swift let encrypted = try ChaCha20(key: key, iv: iv).encrypt(message) let decrypted = try ChaCha20(key: key, iv: iv).decrypt(encrypted) ``` -------------------------------- ### PBKDF2 Password-Based Key Derivation Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Derives a cryptographic key from a password and salt using PBKDF2. Default iterations are 4096 with SHA-256. For high security, increase iterations significantly. Supports both direct calculation and callAsFunction syntax. ```swift import CryptoSwift let password: [UInt8] = Array("s33krit".utf8) let salt: [UInt8] = Array("nacllcan".utf8) // 32-byte AES-256 key let key = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 4096, keyLength: 32, variant: .sha2(.sha256)).calculate() print(key.toHexString()) // deterministic 32-byte key // callAsFunction syntax let key2 = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 10_000, keyLength: 16, variant: .sha2(.sha256))() ``` -------------------------------- ### ChaCha20 Stream Cipher Encryption and Decryption Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Demonstrates basic encryption and decryption using ChaCha20 with a 32-byte key and a 12-byte IETF nonce. Supports an explicit 4-byte counter prefix for protocols like QUIC. ```swift import CryptoSwift let key: [UInt8] = Array(repeating: 0x42, count: 32) // must be 32 bytes let nonce: [UInt8] = Array(repeating: 0x00, count: 12) // 12-byte IETF nonce let chacha = try ChaCha20(key: key, iv: nonce) let message: [UInt8] = Array("Hello, ChaCha20!".utf8) let encrypted = try chacha.encrypt(message) let decrypted = try chacha.decrypt(encrypted) print(String(bytes: decrypted, encoding: .utf8)!) // "Hello, ChaCha20!" // With explicit 4-byte counter (QUIC / RFC 9001) let counter: [UInt8] = [0x00, 0x00, 0x00, 0x01] let chachaWithCounter = try ChaCha20(key: key, counter: counter, iv: nonce) let enc2 = try chachaWithCounter.encrypt(message) ``` ```swift // Streaming var encryptor = chacha.makeEncryptor() var result: [UInt8] = [] result += try (encryptor as! Updatable).update(withBytes: Array("part1".utf8)[...]) result += try (encryptor as! Updatable).update(withBytes: Array("part2".utf8)[...]) result += try (encryptor as! Updatable).update(withBytes: [], isLast: true) ``` ```swift // Data extension let dataMsg = Data(message) let encMsg = try dataMsg.encrypt(cipher: ChaCha20(key: key, iv: nonce)) let decMsg = try encMsg.decrypt(cipher: ChaCha20(key: key, iv: nonce)) ``` -------------------------------- ### Scrypt Memory-Hard Key Derivation Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Derives a cryptographic key using Scrypt, which is designed to be costly in memory and computation to resist brute-force attacks. Parameters N, r, and p control the cost. Supports both direct calculation and callAsFunction syntax. ```swift import CryptoSwift let password: [UInt8] = Array("password".utf8) let salt: [UInt8] = Array("NaCl".utf8) // N=16384, r=8, p=1 — standard interactive login parameters let key = try Scrypt(password: password, salt: salt, dkLen: 64, N: 16384, r: 8, p: 1).calculate() print(key.toHexString()) // deterministic 64-byte output // callAsFunction syntax let key2 = try Scrypt(password: password, salt: salt, dkLen: 32, N: 1024, r: 8, p: 1)() ``` -------------------------------- ### AES - Advanced Encryption Standard Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Supports AES-128, AES-192, and AES-256 with various block modes (CBC, GCM, CCM, etc.) and padding schemes (PKCS#7, no padding, etc.). ```APIDOC ## AES - Advanced Encryption Standard ### Description `AES` is a `final class` supporting AES-128, AES-192, and AES-256. It supports all standard block modes (CBC, GCM, CCM, CTR, CFB, OFB, ECB, PCBC, OCB) and all padding schemes (PKCS#7, PKCS#5, zero, ISO/IEC 7816-4, ISO 10126, no padding). For new designs prefer AES-GCM or AES-CCM. ### Usage #### AES-256 CBC ```swift import CryptoSwift let key: [UInt8] = Array(repeating: 0x00, count: 32) // 32 bytes → AES-256 let iv: [UInt8] = AES.randomIV(AES.blockSize) // 16 random bytes let aes = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) let plaintext: [UInt8] = Array("secret message".utf8) let encrypted = try aes.encrypt(plaintext) let decrypted = try aes.decrypt(encrypted) print(String(bytes: decrypted, encoding: .utf8)!) ``` #### AES-GCM (authenticated encryption) ```swift let gcmIV: [UInt8] = Array(repeating: 0x01, count: 12) let gcm = GCM(iv: gcmIV, mode: .combined) // tag appended to ciphertext let aesGCM = try AES(key: key, blockMode: gcm, padding: .noPadding) let sealedBox = try aesGCM.encrypt(plaintext) let tag = gcm.authenticationTag // available after encryption // Decryption with GCM (provide the known tag) let gcmDec = GCM(iv: gcmIV, authenticationTag: tag!, mode: .combined) let aesGCMDec = try AES(key: key, blockMode: gcmDec, padding: .noPadding) let opened = try aesGCMDec.decrypt(sealedBox) ``` #### Incremental encryption (streaming / large files) ```swift var encryptor = try AES(key: key, blockMode: CBC(iv: iv)).makeEncryptor() var ciphertext: [UInt8] = [] ciphertext += try encryptor.update(withBytes: Array("chunk 1 ".utf8)) ciphertext += try encryptor.update(withBytes: Array("chunk 2".utf8)) ciphertext += try encryptor.finish() ``` #### Data convenience extension ```swift let plain = Data([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10]) let encData = try plain.encrypt(AES(key: key, blockMode: ECB(), padding: .noPadding)) ``` ``` -------------------------------- ### Convert String to Bytes Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Converts a `String` to an `Array` using the `.bytes` extension. ```swift let bytes: Array = "cipherkey".bytes // Array("cipherkey".utf8) ``` -------------------------------- ### Calculate Digests with CryptoSwift Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Use static methods on the Digest struct or extensions on Array, Data, and String for various hash functions. Supports incremental updates for streaming operations. ```swift import CryptoSwift // Static API on Digest let md5Bytes = Digest.md5([0x01, 0x02, 0x03]) let sha256Bytes = Digest.sha256([0x01, 0x02, 0x03]) let sha3Bytes = Digest.sha3([0x01, 0x02, 0x03], variant: .sha256) // Array extensions let input: [UInt8] = Array("hello world".utf8) print(input.md5().toHexString()) // "5eb63bbbe01eeed093cb22bb8f5acdc3" print(input.sha256().toHexString()) // "b94d27b9934d3e08a52e52d7da7..." print(input.sha3(.sha512).toHexString()) // Data extensions let data = Data([0x01, 0x02, 0x03]) let sha1Data: Data = data.sha1() let sha512Data: Data = data.sha512() // String extensions — returns hex-encoded digest directly let hexDigest: String = "hello".md5() // "5d41402abc4b2a76b9719d911017c592" let sha256Hex: String = "hello".sha256() let sha3Hex: String = "hello".sha3(.sha256) // Incremental / streaming SHA-2 var digest = MD5() _ = try digest.update(withBytes: Array("hello ".utf8)) _ = try digest.update(withBytes: Array("world".utf8)) let result = try digest.finish() print(result.toHexString()) ``` -------------------------------- ### XChaCha20 Extended-Nonce Stream Cipher and AEAD Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Implements the XChaCha20 cipher with a 24-byte nonce for safer random nonce generation. Also shows how to use AEAD_XCHACHA20_POLY1305 for authenticated encryption. ```swift import CryptoSwift let key: [UInt8] = Array(repeating: 0x42, count: 32) let longNonce:[UInt8] = Array(repeating: 0x00, count: 24) // 24-byte XChaCha20 nonce // Raw XChaCha20 cipher let xcc = try XChaCha20(key: key, iv: longNonce) let enc = try xcc.encrypt(Array("secret".utf8)) let dec = try xcc.decrypt(enc) ``` ```swift // AEAD_XCHACHA20_POLY1305 authenticated encryption let header: [UInt8] = Array("additional data".utf8) let sealed = try AEADXChaCha20Poly1305.encrypt(Array("plaintext".utf8), key: key, iv: longNonce, authenticationHeader: header) // sealed.cipherText, sealed.authenticationTag let opened = try AEADXChaCha20Poly1305.decrypt(sealed.cipherText, key: key, iv: longNonce, authenticationHeader: header, authenticationTag: sealed.authenticationTag) // opened.plainText, opened.success ``` -------------------------------- ### Add CryptoSwift Dependency (Swift Package Manager) Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Add CryptoSwift as a package dependency in your Swift project using Swift Package Manager. ```swift dependencies: [ .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", from: "1.10.0") ] ``` ```swift .target( name: "MyTarget", dependencies: [ .product(name: "CryptoSwift", package: "CryptoSwift") ] ) ``` -------------------------------- ### Generate RSA Key Pair Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Generate a new RSA key pair (modulus, public exponent, private exponent) with a specified key size in bits. This is a convenient way to create new RSA keys for cryptographic operations. ```swift let rsa = try RSA(keySize: 2048) // This generates a modulus, public exponent and private exponent with the given size ``` -------------------------------- ### AES-CCM Decryption with Authentication Tag Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Demonstrates AES decryption using Counter with Cipher Block Chaining-Message Authentication Code (CCM) mode. The input `encrypted` data is expected to have the authentication tag appended. ```swift do { // `encrypted` contains ciphertext with the authentication tag appended. let tagLength = 8 let ccm = CCM(iv: iv, tagLength: tagLength, messageLength: encrypted.count - tagLength, additionalAuthenticatedData: data) let aes = try AES(key: key, blockMode: ccm, padding: .noPadding) let decrypted = try aes.decrypt(encrypted) } catch { // failed } ``` -------------------------------- ### Poly1305 One-time MAC Generation Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Generates a 16-byte authentication tag using a 32-byte one-time key. Commonly used in ChaCha20-Poly1305 AEAD constructions. The key must be used only once. ```swift import CryptoSwift let oneTimeKey: [UInt8] = Array(repeating: 0x36, count: 32) // must be 32 bytes, use only once let message: [UInt8] = Array("authenticated with poly1305".utf8) let tag = try Poly1305(key: oneTimeKey).authenticate(message) print(tag.toHexString()) // 16-byte tag ``` -------------------------------- ### Add CryptoSwift Dependency (CocoaPods) Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Use CocoaPods to integrate CryptoSwift into your project. Note: CocoaPods is deprecated for new integrations; prefer Swift Package Manager. ```ruby pod 'CryptoSwift', '~> 1.10.0' ``` -------------------------------- ### HKDF HMAC-based Key Derivation Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Extracts and expands keying material using HKDF, suitable for deriving multiple keys from a single shared secret. Supports both direct calculation and callAsFunction syntax. ```swift import CryptoSwift let inputKeyMaterial: [UInt8] = Array("shared secret".utf8) let salt: [UInt8] = Array("random salt".utf8) let info: [UInt8] = Array("context info".utf8) // Derive 32 bytes let derived = try HKDF(password: inputKeyMaterial, salt: salt, info: info, keyLength: 32, variant: .sha2(.sha256)).calculate() print(derived.toHexString()) // 32-byte derived key // callAsFunction syntax let derived2 = try HKDF(password: inputKeyMaterial, salt: salt, keyLength: 64)() ``` -------------------------------- ### AES CBC Encryption without Data Padding Source: https://github.com/krzyzanowskim/cryptoswift/blob/main/README.md Shows AES encryption using CBC mode without any padding. This is useful when the input data is already a multiple of the block size. ```swift let input: Array = [0,1,2,3,4,5,6,7,8,9] let encrypted: Array = try! AES(key: Array("secret0key000000".utf8), blockMode: CBC(iv: Array("0123456789012345".utf8)), padding: .noPadding).encrypt(input) ``` -------------------------------- ### AES Encryption and Decryption with CryptoSwift Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Perform AES encryption and decryption directly on Data objects. Requires a key, block mode (e.g., CBC), and padding scheme (e.g., PKCS7). Ensure correct key and IV sizes for the chosen mode. ```swift // Encryption directly on Data let key: [UInt8] = Array(repeating: 0x00, count: 32) let iv: [UInt8] = Array(repeating: 0x00, count: 16) let cipher = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) let plainData = Data(Array("hello world 1234".utf8)) let encData = try plainData.encrypt(cipher: cipher) let decData = try encData.decrypt(cipher: cipher) ``` -------------------------------- ### Padding Schemes in CryptoSwift Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Adds and removes data padding using various standard schemes like PKCS#7, zero padding, and ISO/IEC 7816-4. PKCS#7 is the default for AES. No padding is also available. ```swift import CryptoSwift let input: [UInt8] = Array("hello".utf8) // 5 bytes // PKCS#7 — most common for block ciphers let padded = Padding.pkcs7.add(to: input, blockSize: AES.blockSize) // 16 bytes let unpadded = Padding.pkcs7.remove(from: padded, blockSize: AES.blockSize) print(unpadded == input) // true // Zero padding let zeroPad = Padding.zeroPadding.add(to: input, blockSize: 8) // 8 bytes // ISO/IEC 7816-4 let isoPad = Padding.iso78164.add(to: input, blockSize: 16) // No padding (stream ciphers or exact-size inputs) let noPad = Padding.noPadding.add(to: input, blockSize: 16) ``` -------------------------------- ### AES Encryption and Decryption with CryptoSwift Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Perform AES encryption and decryption using various modes (CBC, GCM, etc.) and padding schemes. Supports incremental encryption for large data. ```swift import CryptoSwift // AES-256 CBC let key: [UInt8] = Array(repeating: 0x00, count: 32) // 32 bytes → AES-256 let iv: [UInt8] = AES.randomIV(AES.blockSize) // 16 random bytes let aes = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) let plaintext: [UInt8] = Array("secret message".utf8) let encrypted = try aes.encrypt(plaintext) let decrypted = try aes.decrypt(encrypted) print(String(bytes: decrypted, encoding: .utf8)!) // "secret message" // AES-GCM (authenticated encryption) let gcmIV: [UInt8] = Array(repeating: 0x01, count: 12) let gcm = GCM(iv: gcmIV, mode: .combined) // tag appended to ciphertext let aesGCM = try AES(key: key, blockMode: gcm, padding: .noPadding) let sealedBox = try aesGCM.encrypt(plaintext) let tag = gcm.authenticationTag // available after encryption // Decryption with GCM (provide the known tag) let gcmDec = GCM(iv: gcmIV, authenticationTag: tag!, mode: .combined) let aesGCMDec = try AES(key: key, blockMode: gcmDec, padding: .noPadding) let opened = try aesGCMDec.decrypt(sealedBox) // Incremental encryption (streaming / large files) var encryptor = try AES(key: key, blockMode: CBC(iv: iv)).makeEncryptor() var ciphertext: [UInt8] = [] ciphertext += try encryptor.update(withBytes: Array("chunk 1 ".utf8)) ciphertext += try encryptor.update(withBytes: Array("chunk 2".utf8)) ciphertext += try encryptor.finish() // Data convenience extension let plain = Data([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10]) let encData = try plain.encrypt(AES(key: key, blockMode: ECB(), padding: .noPadding)) ``` -------------------------------- ### CMAC Authentication with AES-128 and AES-256 Source: https://context7.com/krzyzanowskim/cryptoswift/llms.txt Implements AES-CMAC (RFC 4493) to produce a 16-byte authentication tag using AES-128/192/256. Useful for verifying data integrity in protocols like IEEE 802.11. ```swift import CryptoSwift let key: [UInt8] = Array(repeating: 0x2b, count: 16) // 16 bytes for AES-128 // AES-CMAC let cmac = try CMAC(key: key) let tag = try cmac.authenticate(Array("message to authenticate".utf8)) print(tag.toHexString()) // 16-byte tag // Authenticate with a custom cipher (e.g. AES-256) let key256: [UInt8] = Array(repeating: 0x00, count: 32) let cmac256 = try CMAC(key: key256) let tag256 = try cmac256.authenticate(Array("message".utf8)) ```