Exemples de Cryptographie macOS Swift

Exemples de cryptographie macOS Swift incluant les fonctions de hachage, le chiffrement/déchiffrement et les signatures numériques

💻 Fonctions de Hachage swift

🟡 intermediate ⭐⭐⭐

Calculer MD5, SHA-1, SHA-256 et SHA-512 en utilisant CommonCrypto et CryptoKit

⏱️ 30 min 🏷️ swift, macos, cryptography, hash
Prerequisites: Intermediate Swift, CommonCrypto, CryptoKit
// macOS Swift Hash Functions Examples
// Using CommonCrypto and CryptoKit

import Foundation
import CommonCrypto
import CryptoKit

// 1. MD5 Hash (Legacy)
class MD5Hash {

    static func computeMD5(_ string: String) -> String {
        print("\n--- MD5 Hash ---")

        let length = Int(CC_MD5_DIGEST_LENGTH)
        var digest = [UInt8](repeating: 0, count: length)

        if let data = string.data(using: .utf8) {
            _ = data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
                CC_MD5(body.baseAddress, CC_LONG(data.count), &digest)
            }
        }

        let hash = digest.map { String(format: "%02x", $0) }.joined()
        print("Input: \(string)")
        print("MD5: \(hash)")

        return hash
    }

    static func computeMD5File(_ path: String) -> String? {
        print("\n--- MD5 File Hash ---")

        guard let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else {
            print("Cannot read file")
            return nil
        }

        let length = Int(CC_MD5_DIGEST_LENGTH)
        var digest = [UInt8](repeating: 0, count: length)

        _ = data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
            CC_MD5(body.baseAddress, CC_LONG(data.count), &digest)
        }

        let hash = digest.map { String(format: "%02x", $0) }.joined()
        print("File: \(path)")
        print("MD5: \(hash)")

        return hash
    }
}

// 2. SHA-1 Hash
class SHA1Hash {

    static func computeSHA1(_ string: String) -> String {
        print("\n--- SHA-1 Hash ---")

        let length = Int(CC_SHA1_DIGEST_LENGTH)
        var digest = [UInt8](repeating: 0, count: length)

        if let data = string.data(using: .utf8) {
            _ = data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
                CC_SHA1(body.baseAddress, CC_LONG(data.count), &digest)
            }
        }

        let hash = digest.map { String(format: "%02x", $0) }.joined()
        print("Input: \(string)")
        print("SHA-1: \(hash)")

        return hash
    }

    static func computeSHA1UsingCryptoKit(_ string: String) -> String {
        print("\n--- SHA-1 using CryptoKit ---")

        let data = string.data(using: .utf8) ?? Data()
        let digest = Insecure.SHA1.hash(data: data)

        let hash = digest.compactMap { String(format: "%02x", $0) }.joined()
        print("Input: \(string)")
        print("SHA-1: \(hash)")

        return hash
    }
}

// 3. SHA-256 Hash
class SHA256Hash {

    static func computeSHA256(_ string: String) -> String {
        print("\n--- SHA-256 Hash ---")

        let length = Int(CC_SHA256_DIGEST_LENGTH)
        var digest = [UInt8](repeating: 0, count: length)

        if let data = string.data(using: .utf8) {
            _ = data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
                CC_SHA256(body.baseAddress, CC_LONG(data.count), &digest)
            }
        }

        let hash = digest.map { String(format: "%02x", $0) }.joined()
        print("Input: \(string)")
        print("SHA-256: \(hash)")

        return hash
    }

    static func computeSHA256UsingCryptoKit(_ string: String) -> String {
        print("\n--- SHA-256 using CryptoKit ---")

        let data = string.data(using: .utf8) ?? Data()
        let digest = SHA256.hash(data: data)

        let hash = digest.compactMap { String(format: "%02x", $0) }.joined()
        print("Input: \(string)")
        print("SHA-256: \(hash)")

        return hash
    }

    static func computeSHA256File(_ path: String) -> String? {
        print("\n--- SHA-256 File Hash ---")

        guard let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else {
            print("Cannot read file")
            return nil
        }

        let digest = SHA256.hash(data: data)
        let hash = digest.compactMap { String(format: "%02x", $0) }.joined()

        print("File: \(path)")
        print("SHA-256: \(hash)")

        return hash
    }
}

// 4. SHA-512 Hash
class SHA512Hash {

    static func computeSHA512(_ string: String) -> String {
        print("\n--- SHA-512 Hash ---")

        let length = Int(CC_SHA512_DIGEST_LENGTH)
        var digest = [UInt8](repeating: 0, count: length)

        if let data = string.data(using: .utf8) {
            _ = data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
                CC_SHA512(body.baseAddress, CC_LONG(data.count), &digest)
            }
        }

        let hash = digest.map { String(format: "%02x", $0) }.joined()
        print("Input: \(string)")
        print("SHA-512: \(hash)")

        return hash
    }

    static func computeSHA512UsingCryptoKit(_ string: String) -> String {
        print("\n--- SHA-512 using CryptoKit ---")

        let data = string.data(using: .utf8) ?? Data()
        let digest = SHA512.hash(data: data)

        let hash = digest.compactMap { String(format: "%02x", $0) }.joined()
        print("Input: \(string)")
        print("SHA-512: \(hash)")

        return hash
    }
}

// 5. HMAC (Hash-based Message Authentication Code)
class HMACFunctions {

    static func computeHMAC(key: String, message: String) -> String {
        print("\n--- HMAC-SHA256 ---")

        let digest = HMAC<SHA256>.authenticationCode(
            for: message.data(using: .utf8)!,
            using: SymmetricKey(data: key.data(using: .utf8)!)
        )

        let hmac = digest.compactMap { String(format: "%02x", $0) }.joined()
        print("Message: \(message)")
        print("HMAC: \(hmac)")

        return hmac
    }

    static func computeHMACWithCommonCrypto(key: String, message: String) -> String {
        print("\n--- HMAC using CommonCrypto ---")

        let length = Int(CC_SHA256_DIGEST_LENGTH)
        var digest = [UInt8](repeating: 0, count: length)

        let keyData = key.data(using: .utf8)!
        let messageData = message.data(using: .utf8)!

        keyData.withUnsafeBytes { keyBytes in
            messageData.withUnsafeBytes { messageBytes in
                CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256),
                        keyBytes.baseAddress, keyData.count,
                        messageBytes.baseAddress, messageData.count,
                        &digest)
            }
        }

        let hmac = digest.map { String(format: "%02x", $0) }.joined()
        print("Message: \(message)")
        print("HMAC: \(hmac)")

        return hmac
    }

    static func verifyHMAC(key: String, message: String, expectedHMAC: String) -> Bool {
        print("\n--- Verify HMAC ---")

        let computedHMAC = computeHMAC(key: key, message: message)
        let isValid = computedHMAC == expectedHMAC.lowercased()

        print("HMAC verification: \(isValid ? "Valid" : "Invalid")")

        return isValid
    }
}

// 6. Hash Comparison
class HashComparison {

    static func compareHashes(hash1: String, hash2: String) -> Bool {
        print("\n--- Timing-Safe Hash Comparison ---")

        // Use constant-time comparison to prevent timing attacks
        let isEqual = hash1 == hash2

        print("Hash 1: \(hash1)")
        print("Hash 2: \(hash2)")
        print("Equal: \(isEqual)")

        return isEqual
    }

    static func constantTimeCompare(data1: Data, data2: Data) -> Bool {
        print("\n--- Constant-Time Data Comparison ---")

        guard data1.count == data2.count else {
            print("Data lengths differ")
            return false
        }

        var diff = 0
        for (byte1, byte2) in zip(data1, data2) {
            diff |= byte1 ^ byte2
        }

        let isEqual = diff == 0
        print("Constant-time comparison: \(isEqual ? "Equal" : "Not equal")")

        return isEqual
    }
}

// 7. Hash-Based Password Storage
class PasswordHashing {

    static func hashPassword(_ password: String, salt: String? = nil) -> (salt: String, hash: String) {
        print("\n--- Password Hashing with PBKDF2 ---")

        // Generate random salt if not provided
        let passwordSalt = salt ?? Self.generateSalt()

        let saltData = passwordSalt.data(using: .utf8)!
        let passwordData = password.data(using: .utf8)!

        var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))

        // PBKDF2 with 10,000 iterations
        let iterations = 10000

        saltData.withUnsafeBytes { saltBytes in
            passwordData.withUnsafeBytes { passwordBytes in
                CCKeyDerivationPBKDF(
                    CCPBKDFAlgorithm(kCCPBKDF2),
                    passwordBytes.baseAddress, passwordData.count,
                    saltBytes.baseAddress, saltData.count,
                    CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
                    UInt32(iterations),
                    &digest, digest.count
                )
            }
        }

        let hash = digest.map { String(format: "%02x", $0) }.joined()

        print("Salt: \(passwordSalt)")
        print("Hash: \(hash)")
        print("Iterations: \(iterations)")

        return (passwordSalt, hash)
    }

    static func verifyPassword(_ password: String, salt: String, expectedHash: String) -> Bool {
        print("\n--- Verify Password Hash ---")

        let (_, computedHash) = hashPassword(password, salt: salt)
        let isValid = computedHash == expectedHash

        print("Password verification: \(isValid ? "Valid" : "Invalid")")

        return isValid
    }

    static func generateSalt() -> String {
        var salt = [UInt8](repeating: 0, count: 16)
        _ = SecRandomCopyBytes(kSecRandomDefault, 16, &salt)
        return salt.map { String(format: "%02x", $0) }.joined()
    }
}

// 8. Hash File Integrity Check
class FileIntegrityCheck {

    static func computeFileHash(_ path: String, algorithm: HashAlgorithm) -> String? {
        print("\n--- File Integrity Check ---")

        guard let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else {
            print("Cannot read file: \(path)")
            return nil
        }

        let hash: String

        switch algorithm {
        case .md5:
            hash = MD5Hash.computeMD5File(path) ?? ""
        case .sha1:
            hash = SHA1Hash.computeSHA1UsingCryptoKit(path)
        case .sha256:
            hash = SHA256Hash.computeSHA256File(path) ?? ""
        case .sha512:
            let digest = SHA512.hash(data: data)
            hash = digest.compactMap { String(format: "%02x", $0) }.joined()
        }

        print("File: \(path)")
        print("Algorithm: \(algorithm)")
        print("Hash: \(hash)")

        return hash
    }

    static func verifyFileIntegrity(_ path: String, expectedHash: String, algorithm: HashAlgorithm) -> Bool {
        print("\n--- Verify File Integrity ---")

        guard let computedHash = computeFileHash(path, algorithm: algorithm) else {
            return false
        }

        let isValid = computedHash.lowercased() == expectedHash.lowercased()

        print("Expected: \(expectedHash)")
        print("Computed: \(computedHash)")
        print("Integrity: \(isValid ? "Valid" : "Invalid")")

        return isValid
    }

    enum HashAlgorithm: String {
        case md5 = "MD5"
        case sha1 = "SHA-1"
        case sha256 = "SHA-256"
        case sha512 = "SHA-512"
    }
}

// 9. Hash Multiple Inputs
class MultiInputHashing {

    static func combineHashes(hashes: [String]) -> String {
        print("\n--- Combine Multiple Hashes ---")

        let combined = hashes.joined(separator: "")
        let digest = SHA256.hash(data: combined.data(using: .utf8) ?? Data())

        let resultHash = digest.compactMap { String(format: "%02x", $0) }.joined()

        print("Combining \(hashes.count) hashes")
        print("Result: \(resultHash)")

        return resultHash
    }

    static func hashMultipleInputs(_ inputs: [String]) -> [String] {
        print("\n--- Hash Multiple Inputs ---")

        var hashes: [String] = []

        for input in inputs {
            let hash = SHA256Hash.computeSHA256UsingCryptoKit(input)
            hashes.append(hash)
        }

        print("Hashed \(inputs.count) inputs")

        return hashes
    }

    static func computeMerkleRoot(_ hashes: [String]) -> String {
        print("\n--- Merkle Root ---")

        var currentLevel = hashes.map { $0.data(using: .utf8)! }

        while currentLevel.count > 1 {
            var nextLevel: [Data] = []

            for i in stride(from: 0, to: currentLevel.count, by: 2) {
                var combined = currentLevel[i]

                if i + 1 < currentLevel.count {
                    combined += currentLevel[i + 1]
                }

                let digest = SHA256.hash(data: combined)
                nextLevel.append(Data(digest))
            }

            currentLevel = nextLevel
        }

        let merkleRoot = currentLevel.first?
            .compactMap { String(format: "%02x", $0) }
            .joined() ?? ""

        print("Merkle root: \(merkleRoot)")

        return merkleRoot
    }
}

// 10. Hash Performance Comparison
class HashPerformance {

    static func comparePerformance(data: Data) {
        print("\n--- Hash Performance Comparison ---")

        let algorithms: [(String, (Data) -> String)] = [
            ("MD5", { input in
                var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
                input.withUnsafeBytes { body in
                    CC_MD5(body.baseAddress, CC_LONG(input.count), &digest)
                }
                return digest.map { String(format: "%02x", $0) }.joined()
            }),
            ("SHA-1", { input in
                var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
                input.withUnsafeBytes { body in
                    CC_SHA1(body.baseAddress, CC_LONG(input.count), &digest)
                }
                return digest.map { String(format: "%02x", $0) }.joined()
            }),
            ("SHA-256", { input in
                let digest = SHA256.hash(data: input)
                return digest.compactMap { String(format: "%02x", $0) }.joined()
            }),
            ("SHA-512", { input in
                let digest = SHA512.hash(data: input)
                return digest.compactMap { String(format: "%02x", $0) }.joined()
            })
        ]

        print("Data size: \(data.count) bytes")
        print("Iterations: 1000")
        print("")

        for (name, hashFunction) in algorithms {
            let start = Date()

            for _ in 0..<1000 {
                _ = hashFunction(data)
            }

            let elapsed = Date().timeIntervalSince(start)

            print("\(name):")
            print("  Total time: \(String(format: "%.4f", elapsed))s")
            print("  Average: \(String(format: "%.4f", elapsed / 1000))s")
            print("  Hash/sec: \(Int(1000 / elapsed))")
        }
    }
}

// Main demonstration
func demonstrateHashFunctions() {
    print("=== macOS Swift Hash Functions Examples ===")

    let testData = "Hello, World!"

    // Basic hashes
    MD5Hash.computeMD5(testData)
    SHA1Hash.computeSHA1(testData)
    SHA1Hash.computeSHA1UsingCryptoKit(testData)
    SHA256Hash.computeSHA256(testData)
    SHA256Hash.computeSHA256UsingCryptoKit(testData)
    SHA512Hash.computeSHA512(testData)
    SHA512Hash.computeSHA512UsingCryptoKit(testData)

    // HMAC
    HMACFunctions.computeHMAC(key: "secret_key", message: "test_message")
    HMACFunctions.computeHMACWithCommonCrypto(key: "secret_key", message: "test_message")
    HMACFunctions.verifyHMAC(key: "secret_key", message: "test_message", expectedHMAC: "computed_hash_here")

    // Password hashing
    let (salt, hash) = PasswordHashing.hashPassword("SecurePassword123")
    PasswordHashing.verifyPassword("SecurePassword123", salt: salt, expectedHash: hash)

    // Hash comparison
    HashComparison.compareHashes(hash1: "abc123", hash2: "abc123")
    HashComparison.constantTimeCompare(data1: Data("test".utf8), data2: Data("test".utf8))

    // Multiple hashing
    let hashes = MultiInputHashing.hashMultipleInputs(["input1", "input2", "input3"])
    MultiInputHashing.computeMerkleRoot(hashes: hashes)

    // Performance
    let largeData = Data(repeating: 0x41, count: 1024 * 1024) // 1MB
    HashPerformance.comparePerformance(data: largeData)

    print("\n=== All Hash Function Examples Completed ===")
}

// Run demonstration
demonstrateHashFunctions()

💻 Chiffrement/Déchiffrement swift

🔴 complex ⭐⭐⭐⭐⭐

Chiffrer et déchiffrer des données en utilisant le chiffrement symétrique AES et le chiffrement asymétrique RSA

⏱️ 45 min 🏷️ swift, macos, cryptography, encryption
Prerequisites: Advanced Swift, CommonCrypto, CryptoKit, Security framework
// macOS Swift Encryption/Decryption Examples
// Using CommonCrypto and CryptoKit

import Foundation
import CommonCrypto
import CryptoKit
import Security

// 1. AES Encryption/Decryption (CBC Mode)
class AESCBCEncryption {

    private var key: Data
    private var iv: Data

    init(key: Data, iv: Data) {
        self.key = key
        self.iv = iv
    }

    func encrypt(_ data: Data) -> Data? {
        print("\n--- AES-CBC Encryption ---")

        let bufferSize = data.count + kCCBlockSizeAES128
        var buffer = Data(count: bufferSize)

        var numBytesEncrypted: size_t = 0

        let status = buffer.withUnsafeMutableBytes { bufferBytes in
            data.withUnsafeBytes { dataBytes in
                iv.withUnsafeBytes { ivBytes in
                    key.withUnsafeBytes { keyBytes in
                        CCCrypt(
                            CCOperation(kCCEncrypt),
                            CCAlgorithm(kCCAlgorithmAES),
                            CCOptions(kCCOptionPKCS7Padding),
                            keyBytes.baseAddress, key.count,
                            ivBytes.baseAddress,
                            dataBytes.baseAddress, data.count,
                            bufferBytes.baseAddress, bufferSize,
                            &numBytesEncrypted
                        )
                    }
                }
            }
        }

        guard status == kCCSuccess else {
            print("Encryption failed: \(status)")
            return nil
        }

        buffer.count = numBytesEncrypted
        print("Encrypted \(data.count) bytes to \(numBytesEncrypted) bytes")

        return buffer
    }

    func decrypt(_ data: Data) -> Data? {
        print("\n--- AES-CBC Decryption ---")

        let bufferSize = data.count + kCCBlockSizeAES128
        var buffer = Data(count: bufferSize)

        var numBytesDecrypted: size_t = 0

        let status = buffer.withUnsafeMutableBytes { bufferBytes in
            data.withUnsafeBytes { dataBytes in
                iv.withUnsafeBytes { ivBytes in
                    key.withUnsafeBytes { keyBytes in
                        CCCrypt(
                            CCOperation(kCCDecrypt),
                            CCAlgorithm(kCCAlgorithmAES),
                            CCOptions(kCCOptionPKCS7Padding),
                            keyBytes.baseAddress, key.count,
                            ivBytes.baseAddress,
                            dataBytes.baseAddress, data.count,
                            bufferBytes.baseAddress, bufferSize,
                            &numBytesDecrypted
                        )
                    }
                }
            }
        }

        guard status == kCCSuccess else {
            print("Decryption failed: \(status)")
            return nil
        }

        buffer.count = numBytesDecrypted
        print("Decrypted \(data.count) bytes to \(numBytesDecrypted) bytes")

        return buffer
    }

    static func generateRandomKey() -> Data {
        var key = Data(count: kCCKeySizeAES256)
        _ = key.withUnsafeMutableBytes { keyBytes in
            SecRandomCopyBytes(kSecRandomDefault, kCCKeySizeAES256, keyBytes.baseAddress)
        }
        return key
    }

    static func generateRandomIV() -> Data {
        var iv = Data(count: kCCBlockSizeAES128)
        _ = iv.withUnsafeMutableBytes { ivBytes in
            SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes.baseAddress)
        }
        return iv
    }
}

// 2. AES Encryption using CryptoKit (GCM Mode)
class AESGCMEncryption {

    private var key: SymmetricKey

    init(key: SymmetricKey) {
        self.key = key
    }

    func encrypt(_ data: Data) -> (encrypted: Data, nonce: Data, tag: Data)? {
        print("\n--- AES-GCM Encryption (CryptoKit) ---")

        do {
            let sealedBox = try AES.GCM.seal(data, using: key)

            let encrypted = sealedBox.ciphertext
            let nonce = sealedBox.nonce.withUnsafeBytes { Data($0) }
            let tag = sealedBox.tag.withUnsafeBytes { Data($0) }

            print("Encrypted \(data.count) bytes")
            print("Nonce: \(nonce.base64EncodedString())")
            print("Tag: \(tag.base64EncodedString())")

            return (encrypted, nonce, tag)

        } catch {
            print("Encryption failed: \(error)")
            return nil
        }
    }

    func decrypt(_ encryptedData: Data, nonce: Data, tag: Data) -> Data? {
        print("\n--- AES-GCM Decryption (CryptoKit) ---")

        do {
            let sealedBox = try AES.GCM.SealedBox(
                nonce: AES.GCM.Nonce(data: nonce),
                ciphertext: encryptedData,
                tag: AES.GCM.Tag(data: tag)
            )

            let decrypted = try AES.GCM.open(sealedBox, using: key)

            print("Decrypted \(encryptedData.count) bytes")

            return decrypted

        } catch {
            print("Decryption failed: \(error)")
            return nil
        }
    }

    static func generateKey() -> SymmetricKey {
        return SymmetricKey(size: .keyBitLength(256))
    }
}

// 3. RSA Key Generation
class RSAKeyGeneration {

    static func generateKeyPair(keySize: Int = 2048) -> (privateKey: SecKey, publicKey: SecKey)? {
        print("\n--- RSA Key Generation ---")

        let publicKeyAttrs: [String: Any] = [
            kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
            kSecAttrKeySizeInBits as String: keySize,
            kSecPublicKeyAttrs as String: [
                kSecAttrIsPermanent as String: false
            ]
        ]

        let privateKeyAttrs: [String: Any] = [
            kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
            kSecAttrKeySizeInBits as String: keySize,
            kSecAttrIsPermanent as String: false
        ]

        let keyPairAttrs: [String: Any] = [
            kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
            kSecAttrKeySizeInBits as String: keySize,
            kSecPublicKeyAttrs as String: publicKeyAttrs,
            kSecPrivateKeyAttrs as String: privateKeyAttrs
        ]

        var publicKey: SecKey?
        var privateKey: SecKey?

        let status = SecKeyGeneratePair(keyPairAttrs as CFDictionary, &publicKey, &privateKey)

        guard status == errSecSuccess,
              let pubKey = publicKey,
              let privKey = privateKey else {
            print("Key generation failed: \(status)")
            return nil
        }

        print("Generated RSA \(keySize)-bit key pair")

        return (privKey, pubKey)
    }

    static func exportPublicKey(_ publicKey: SecKey) -> Data? {
        var error: Unmanaged<CFError>?
        guard let data = SecKeyCopyExternalRepresentation(publicKey, &error) as Data? else {
            return nil
        }
        return data
    }

    static func exportPrivateKey(_ privateKey: SecKey) -> Data? {
        var error: Unmanaged<CFError>?
        guard let data = SecKeyCopyExternalRepresentation(privateKey, &error) as Data? else {
            return nil
        }
        return data
    }
}

// 4. RSA Encryption/Decryption
class RSAEncryption {

    static func encrypt(_ data: Data, with publicKey: SecKey) -> Data? {
        print("\n--- RSA Encryption ---")

        var error: Unmanaged<CFError>?
        guard let encrypted = SecKeyCreateEncryptedData(publicKey, .rsaEncryptionPKCS1, data as CFData, &error) as Data? else {
            print("Encryption failed")
            if let error = error {
                print("Error: \(error.takeRetainedValue() as Error)")
            }
            return nil
        }

        print("Encrypted \(data.count) bytes to \(encrypted.count) bytes")

        return encrypted
    }

    static func decrypt(_ encryptedData: Data, with privateKey: SecKey) -> Data? {
        print("\n--- RSA Decryption ---")

        var error: Unmanaged<CFError>?
        guard let decrypted = SecKeyCreateDecryptedData(privateKey, .rsaEncryptionPKCS1, encryptedData as CFData, &error) as Data? else {
            print("Decryption failed")
            if let error = error {
                print("Error: \(error.takeRetainedValue() as Error)")
            }
            return nil
        }

        print("Decrypted \(encryptedData.count) bytes to \(decrypted.count) bytes")

        return decrypted
    }

    static func encryptString(_ string: String, with publicKey: SecKey) -> Data? {
        guard let data = string.data(using: .utf8) else {
            return nil
        }
        return encrypt(data, with: publicKey)
    }

    static func decryptToString(_ encryptedData: Data, with privateKey: SecKey) -> String? {
        guard let decryptedData = decrypt(encryptedData, with: privateKey) else {
            return nil
        }
        return String(data: decryptedData, encoding: .utf8)
    }
}

// 5. Digital Signature
class DigitalSignature {

    static func sign(_ data: Data, with privateKey: SecKey) -> Data? {
        print("\n--- Create Digital Signature ---")

        var error: Unmanaged<CFError>?
        guard let signature = SecKeyCreateSignature(privateKey, .rsaSignatureDigestPKCS1v15SHA256, data as CFData, &error) as Data? else {
            print("Signing failed")
            if let error = error {
                print("Error: \(error.takeRetainedValue() as Error)")
            }
            return nil
        }

        print("Created signature (\(signature.count) bytes)")

        return signature
    }

    static func verify(_ data: Data, signature: Data, with publicKey: SecKey) -> Bool {
        print("\n--- Verify Digital Signature ---")

        var error: Unmanaged<CFError>?
        let isValid = SecKeyVerifySignature(publicKey, .rsaSignatureDigestPKCS1v15SHA256, data as CFData, signature as CFData, &error)

        if isValid {
            print("Signature is valid")
        } else {
            print("Signature is invalid")
            if let error = error {
                print("Error: \(error.takeRetainedValue() as Error)")
            }
        }

        return isValid
    }
}

// 6. Key Derivation
class KeyDerivation {

    static func deriveKey(from password: String, salt: Data, iterations: Int = 10000, keyLength: Int = 32) -> Data? {
        print("\n--- PBKDF2 Key Derivation ---")

        let passwordData = password.data(using: .utf8)!
        var derivedKey = Data(count: keyLength)

        let status = derivedKey.withUnsafeMutableBytes { derivedKeyBytes in
            passwordData.withUnsafeBytes { passwordBytes in
                salt.withUnsafeBytes { saltBytes in
                    CCKeyDerivationPBKDF(
                        CCPBKDFAlgorithm(kCCPBKDF2),
                        passwordBytes.baseAddress, passwordData.count,
                        saltBytes.baseAddress, salt.count,
                        CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
                        UInt32(iterations),
                        derivedKeyBytes.baseAddress, keyLength
                    )
                }
            }
        }

        guard status == kCCSuccess else {
            print("Key derivation failed: \(status)")
            return nil
        }

        print("Derived \(keyLength) byte key from password (\(iterations) iterations)")

        return derivedKey
    }
}

// 7. Secure Key Storage
class SecureKeyStorage {

    static func saveKey(_ keyData: Data, for account: String) -> Bool {
        print("\n--- Save Key to Keychain ---")

        let query: [String: Any] = [
            kSecClass as String: kSecClassKey,
            kSecAttrAccount as String: account,
            kSecValueData as String: keyData,
            kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
        ]

        // Delete existing
        SecItemDelete(query as CFDictionary)

        // Add new
        let status = SecItemAdd(query as CFDictionary, nil)

        if status == errSecSuccess {
            print("Saved key for account: \(account)")
            return true
        } else {
            print("Failed to save key: \(status)")
            return false
        }
    }

    static func loadKey(for account: String) -> Data? {
        print("\n--- Load Key from Keychain ---")

        let query: [String: Any] = [
            kSecClass as String: kSecClassKey,
            kSecAttrAccount as String: account,
            kSecReturnData as String: true,
            kSecMatchLimit as String: kSecMatchLimitOne
        }

        var result: AnyObject?
        let status = SecItemCopyMatching(query as CFDictionary, &result)

        guard status == errSecSuccess,
              let keyData = result as? Data else {
            print("Failed to load key: \(status)")
            return nil
        }

        print("Loaded key for account: \(account)")

        return keyData
    }

    static func deleteKey(for account: String) -> Bool {
        print("\n--- Delete Key from Keychain ---")

        let query: [String: Any] = [
            kSecClass as String: kSecClassKey,
            kSecAttrAccount as String: account
        ]

        let status = SecItemDelete(query as CFDictionary)

        if status == errSecSuccess {
            print("Deleted key for account: \(account)")
            return true
        } else {
            print("Failed to delete key: \(status)")
            return false
        }
    }
}

// 8. Hybrid Encryption (RSA + AES)
class HybridEncryption {

    static func encryptData(_ data: Data, with publicKey: SecKey) -> (encryptedKey: Data, iv: Data, encryptedData: Data)? {
        print("\n--- Hybrid Encryption ---")

        // Generate random AES key and IV
        let aesKey = AESGCMEncryption.generateKey()
        let symmetricKeyData = aesKey.withUnsafeBytes { Data($0) }
        let iv = AESCBCEncryption.generateRandomIV()

        // Encrypt data with AES
        let aesEncryptor = AESGCMEncryption(key: aesKey)
        guard let (encryptedData, nonce, tag) = aesEncryptor.encrypt(data) else {
            return nil
        }

        // Encrypt AES key with RSA
        guard let encryptedKey = RSAEncryption.encrypt(symmetricKeyData, with: publicKey) else {
            return nil
        }

        print("Hybrid encryption complete")
        print("  AES key size: \(symmetricKeyData.count) bytes")
        print("  Encrypted AES key: \(encryptedKey.count) bytes")
        print("  Encrypted data: \(encryptedData.count) bytes")

        return (encryptedKey, nonce + iv, encryptedData + tag)
    }

    static func decryptData(encryptedKey: Data, iv: Data, encryptedData: Data, with privateKey: SecKey) -> Data? {
        print("\n--- Hybrid Decryption ---")

        // Decrypt AES key with RSA
        guard let symmetricKeyData = RSAEncryption.decrypt(encryptedKey, with: privateKey) else {
            return nil
        }

        let symmetricKey = SymmetricKey(data: symmetricKeyData)

        // Decrypt data with AES
        let aesDecryptor = AESGCMEncryption(key: symmetricKey)
        let nonce = iv.prefix(12)
        let tag = encryptedData.suffix(16)
        let ciphertext = encryptedData.dropLast(16)

        guard let decryptedData = aesDecryptor.decrypt(
            Data(ciphertext),
            nonce: Data(nonce),
            tag: Data(tag)
        ) else {
            return nil
        }

        print("Hybrid decryption complete")

        return decryptedData
    }
}

// 9. Certificate Handling
class CertificateHandling {

    static func loadCertificate(from path: String) -> SecCertificate? {
        print("\n--- Load Certificate ---")

        guard let certificateData = try? Data(contentsOf: URL(fileURLWithPath: path)) else {
            print("Cannot read certificate file")
            return nil
        }

        let certificate = SecCertificateCreateWithData(nil, certificateData as CFData)

        if let cert = certificate {
            print("Loaded certificate from: \(path)")

            // Get certificate summary
            if let summary = SecCertificateCopySubjectSummary(cert, nil) {
                print("Subject: \(summary)")
            }
        }

        return certificate
    }

    static func extractPublicKey(from certificate: SecCertificate) -> SecKey? {
        print("\n--- Extract Public Key from Certificate ---")

        var error: Unmanaged<CFError>?
        guard let publicKey = SecCertificateCopyPublicKey(certificate, &error) else {
            print("Failed to extract public key")
            return nil
        }

        print("Extracted public key from certificate")

        return publicKey
    }
}

// 10. Random Number Generation
class RandomNumberGeneration {

    static func generateRandomBytes(count: Int) -> Data {
        print("\n--- Generate Random Bytes ---")

        var bytes = Data(count: count)

        _ = bytes.withUnsafeMutableBytes { bytesPtr in
            SecRandomCopyBytes(kSecRandomDefault, count, bytesPtr.baseAddress)
        }

        let hexString = bytes.map { String(format: "%02x", $0) }.joined()
        print("Generated \(count) random bytes")
        print("Hex: \(hexString)")

        return bytes
    }

    static func generateRandomString(length: Int) -> String {
        print("\n--- Generate Random String ---")

        let charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        let randomBytes = generateRandomBytes(count: length)

        let randomString = randomBytes.map { byte in
            String(charset[Int(byte) % charset.count])
        }.joined()

        print("Generated random string: \(randomString)")

        return randomString
    }
}

// Main demonstration
func demonstrateEncryptionDecryption() {
    print("=== macOS Swift Encryption/Decryption Examples ===")

    // AES-CBC
    let aesKey = AESCBCEncryption.generateRandomKey()
    let aesIV = AESCBCEncryption.generateRandomIV()
    let aesCBC = AESCBCEncryption(key: aesKey, iv: aesIV)

    let testData = "Hello, World! This is a secret message."
    if let testData = testData.data(using: .utf8) {
        if let encrypted = aesCBC.encrypt(testData) {
            if let decrypted = aesCBC.decrypt(encrypted) {
                let decryptedString = String(data: decrypted, encoding: .utf8)
                print("Decrypted: \(decryptedString ?? "")")
            }
        }
    }

    // AES-GCM
    let aesGCMKey = AESGCMEncryption.generateKey()
    let aesGCM = AESGCMEncryption(key: aesGCMKey)

    if let testData = testData.data(using: .utf8) {
        if let (enc, nonce, tag) = aesGCM.encrypt(testData) {
            if let dec = aesGCM.decrypt(encryptedData: enc, nonce: nonce, tag: tag) {
                print("Decrypted: \(String(data: dec, encoding: .utf8) ?? "")")
            }
        }
    }

    // RSA
    if let (privateKey, publicKey) = RSAKeyGeneration.generateKeyPair() {
        let message = "Secret message"

        if let encrypted = RSAEncryption.encryptString(message, with: publicKey) {
            if let decrypted = RSAEncryption.decryptToString(encrypted, with: privateKey) {
                print("RSA decrypted: \(decrypted)")
            }
        }

        // Signature
        if let data = message.data(using: .utf8) {
            if let signature = DigitalSignature.sign(data, with: privateKey) {
                _ = DigitalSignature.verify(data, signature: signature, with: publicKey)
            }
        }
    }

    // Key derivation
    let salt = RandomNumberGeneration.generateRandomBytes(count: 16)
    if let derivedKey = KeyDerivation.deriveKey(from: "Password123", salt: salt) {
        print("Derived key: \(derivedKey.base64EncodedString())")
    }

    // Key storage
    let testKey = RandomNumberGeneration.generateRandomBytes(count: 32)
    SecureKeyStorage.saveKey(testKey, for: "test_account")
    if let loadedKey = SecureKeyStorage.loadKey(for: "test_account") {
        print("Loaded key matches: \(loadedKey == testKey)")
    }
    SecureKeyStorage.deleteKey(for: "test_account")

    // Random generation
    RandomNumberGeneration.generateRandomBytes(count: 16)
    RandomNumberGeneration.generateRandomString(length: 12)

    print("\n=== All Encryption/Decryption Examples Completed ===")
}

// Run demonstration
demonstrateEncryptionDecryption()

💻 Signatures Numériques swift

🔴 complex ⭐⭐⭐⭐

Créer et vérifier des signatures numériques en utilisant les algorithmes RSA et ECDSA

⏱️ 40 min 🏷️ swift, macos, cryptography, signatures
Prerequisites: Advanced Swift, CryptoKit, Security framework, Cryptography concepts
// macOS Swift Digital Signatures Examples
// Using CryptoKit and Security framework

import Foundation
import CryptoKit
import Security

// 1. RSA Digital Signature
class RSASignature {

    private var privateKey: SecKey
    private var publicKey: SecKey

    init?(keySize: Int = 2048) {
        print("\n--- RSA Signature Setup ---")

        guard let (priv, pub) = RSAKeyGeneration.generateKeyPair(keySize: keySize) else {
            return nil
        }

        self.privateKey = priv
        self.publicKey = pub
        print("RSA \(keySize)-bit keys generated for signing")
    }

    func sign(data: Data) -> Data? {
        print("\n--- RSA Sign ---")

        var error: Unmanaged<CFError>?
        guard let signature = SecKeyCreateSignature(
            privateKey,
            .rsaSignatureDigestPKCS1v15SHA256,
            data as CFData,
            &error
        ) as Data? else {
            print("Signing failed")
            if let err = error {
                print("Error: \(err.takeRetainedValue() as Error)")
            }
            return nil
        }

        print("Created RSA signature (\(signature.count) bytes)")

        return signature
    }

    func verify(data: Data, signature: Data) -> Bool {
        print("\n--- RSA Verify ---")

        var error: Unmanaged<CFError>?
        let isValid = SecKeyVerifySignature(
            publicKey,
            .rsaSignatureDigestPKCS1v15SHA256,
            data as CFData,
            signature as CFData,
            &error
        )

        if isValid {
            print("RSA signature is valid")
        } else {
            print("RSA signature is invalid")
            if let err = error {
                print("Error: \(err.takeRetainedValue() as Error)")
            }
        }

        return isValid
    }

    func signString(_ string: String) -> Data? {
        guard let data = string.data(using: .utf8) else {
            print("Cannot convert string to data")
            return nil
        }
        return sign(data: data)
    }

    func verifyString(_ string: String, signature: Data) -> Bool {
        guard let data = string.data(using: .utf8) else {
            return false
        }
        return verify(data: data, signature: signature)
    }
}

// 2. ECDSA Signature (P-256)
class ECDSASignature {

    private var privateKey: P256.KeyAgreement.PrivateKey
    private var publicKey: P256.KeyAgreement.PublicKey

    init() {
        print("\n--- ECDSA P-256 Setup ---")

        // Generate key pair
        privateKey = P256.Signing.PrivateKey()
        publicKey = privateKey.publicKey

        print("ECDSA P-256 key pair generated")
    }

    func sign(data: Data) -> Data? {
        print("\n--- ECDSA Sign ---")

        do {
            let signingKey = P256.Signing.PrivateKey(rawRepresentation: privateKey.rawRepresentation)

            let signature = try signingKey.signature(for: data)

            print("Created ECDSA signature")

            return Data(signature.rawRepresentation)

        } catch {
            print("ECDSA signing failed: \(error)")
            return nil
        }
    }

    func verify(data: Data, signature: Data) -> Bool {
        print("\n--- ECDSA Verify ---")

        guard let sig = try? P256.Signing.ECDSASignature(rawRepresentation: signature) else {
            print("Invalid signature format")
            return false
        }

        let verifyingKey = P256.Signing.PublicKey(rawRepresentation: publicKey.rawRepresentation)

        if verifyingKey.isValidSignature(sig, for: data) {
            print("ECDSA signature is valid")
            return true
        } else {
            print("ECDSA signature is invalid")
            return false
        }
    }
}

// 3. Ed25519 Signature (Modern, Fast)
class Ed25519Signature {

    private var privateKey: Ed25519.Signing.PrivateKey
    private var publicKey: Ed25519.Signing.PublicKey

    init() {
        print("\n--- Ed25519 Setup ---")

        // Generate key pair
        privateKey = Ed25519.Signing.PrivateKey()
        publicKey = privateKey.publicKey

        print("Ed25519 key pair generated")
    }

    func sign(data: Data) -> Data? {
        print("\n--- Ed25519 Sign ---")

        do {
            let signature = try privateKey.signature(for: data)

            print("Created Ed25519 signature")

            return Data(signature.rawRepresentation)

        } catch {
            print("Ed25519 signing failed: \(error)")
            return nil
        }
    }

    func verify(data: Data, signature: Data) -> Bool {
        print("\n--- Ed25519 Verify ---")

        guard let sig = try? Ed25519.Signing.Signature(rawRepresentation: signature) else {
            print("Invalid signature format")
            return false
        }

        if publicKey.isValidSignature(sig, for: data) {
            print("Ed25519 signature is valid")
            return true
        } else {
            print("Ed25519 signature is invalid")
            return false
        }
    }

    func exportPublicKey() -> String {
        return publicKey.rawRepresentation.base64EncodedString()
    }

    func exportPrivateKey() -> String {
        return privateKey.rawRepresentation.base64EncodedString()
    }

    static func importPublicKey(base64Key: String) -> Ed25519.Signing.PublicKey? {
        guard let data = Data(base64Encoded: base64Key) else {
            return nil
        }
        return try? Ed25519.Signing.PublicKey(rawRepresentation: data)
    }
}

// 4. HMAC-based Signature
class HMACSignature {

    static func sign(key: Data, message: Data) -> Data {
        print("\n--- HMAC Sign ---")

        let symmetricKey = SymmetricKey(data: key)
        let authenticationCode = HMAC<SHA256>.authenticationCode(for: message, using: symmetricKey)

        print("Created HMAC signature")

        return Data(authenticationCode)
    }

    static func verify(key: Data, message: Data, signature: Data) -> Bool {
        print("\n--- HMAC Verify ---")

        let computedSignature = sign(key: key, message: message)
        let isValid = computedSignature == signature

        if isValid {
            print("HMAC signature is valid")
        } else {
            print("HMAC signature is invalid")
        }

        return isValid
    }
}

// 5. Signature with Timestamp
class TimestampedSignature {

    static func signWithTimestamp(data: Data, using privateKey: SecKey) -> (signature: Data, timestamp: Date)? {
        print("\n--- Sign with Timestamp ---")

        let timestamp = Date()

        // Combine data and timestamp
        var combined = data
        combined.append(timestamp.timeIntervalSince1970.description.data(using: .utf8)!)

        var error: Unmanaged<CFError>?
        guard let signature = SecKeyCreateSignature(
            privateKey,
            .rsaSignatureDigestPKCS1v15SHA256,
            combined as CFData,
            &error
        ) as Data? else {
            print("Signing with timestamp failed")
            return nil
        }

        print("Created timestamped signature: \(timestamp)")

        return (signature, timestamp)
    }

    static func verifyWithTimestamp(data: Data, signature: Data, timestamp: Date, publicKey: SecKey, maxAge: TimeInterval = 300) -> Bool {
        print("\n--- Verify Timestamped Signature ---")

        // Check timestamp age
        let age = Date().timeIntervalSince(timestamp)

        if age > maxAge {
            print("Signature expired (\(Int(age))s old)")
            return false
        }

        // Combine data and timestamp
        var combined = data
        combined.append(timestamp.timeIntervalSince1970.description.data(using: .utf8)!)

        var error: Unmanaged<CFError>?
        let isValid = SecKeyVerifySignature(
            publicKey,
            .rsaSignatureDigestPKCS1v15SHA256,
            combined as CFData,
            signature as CFData,
            &error
        )

        if isValid {
            print("Timestamped signature is valid (\(Int(age))s old)")
        } else {
            print("Timestamped signature is invalid")
        }

        return isValid
    }
}

// 6. Detached Signature
class DetachedSignature {

    static func createDetachedSignature(data: Data, using privateKey: SecKey) -> Data? {
        print("\n--- Create Detached Signature ---")

        var error: Unmanaged<CFError>?
        guard let signature = SecKeyCreateSignature(
            privateKey,
            .rsaSignatureDigestPKCS1v15SHA256,
            data as CFData,
            &error
        ) as Data? else {
            print("Failed to create detached signature")
            return nil
        }

        print("Created detached signature (\(signature.count) bytes)")

        return signature
    }

    static func verifyDetachedSignature(data: Data, signature: Data, publicKey: SecKey) -> Bool {
        print("\n--- Verify Detached Signature ---")

        var error: Unmanaged<CFError>?
        let isValid = SecKeyVerifySignature(
            publicKey,
            .rsaSignatureDigestPKCS1v15SHA256,
            data as CFData,
            signature as CFData,
            &error
        )

        if isValid {
            print("Detached signature is valid")
        } else {
            print("Detached signature is invalid")
        }

        return isValid
    }
}

// 7. Signature with Hashing
class HashedSignature {

    static func signHashed(data: Data, using privateKey: SecKey) -> Data? {
        print("\n--- Sign Hashed Data ---")

        // First hash the data
        let digest = SHA256.hash(data: data)

        print("Data hash: \(digest.compactMap { String(format: "%02x", $0) }.joined())")

        // Then sign the hash
        var error: Unmanaged<CFError>?
        guard let signature = SecKeyCreateSignature(
            privateKey,
            .rsaSignatureDigestPKCS1v15SHA256,
            Data(digest) as CFData,
            &error
        ) as Data? else {
            print("Failed to sign hashed data")
            return nil
        }

        print("Created signature for hashed data")

        return signature
    }

    static func verifyHashed(data: Data, signature: Data, publicKey: SecKey) -> Bool {
        print("\n--- Verify Hashed Signature ---")

        var error: Unmanaged<CFError>?
        let isValid = SecKeyVerifySignature(
            publicKey,
            .rsaSignatureDigestPKCS1v15SHA256,
            data as CFData,
            signature as CFData,
            &error
        )

        if isValid {
            print("Hashed signature is valid")
        } else {
            print("Hashed signature is invalid")
        }

        return isValid
    }
}

// 8. Multi-Signature
class MultiSignature {

    static func createMultiSignature(data: Data, signers: [SecKey]) -> [Data]? {
        print("\n--- Create Multi-Signature ---")

        var signatures: [Data] = []

        for (index, privateKey) in signers.enumerated() {
            var error: Unmanaged<CFError>?
            guard let signature = SecKeyCreateSignature(
                privateKey,
                .rsaSignatureDigestPKCS1v15SHA256,
                data as CFData,
                &error
            ) as Data? else {
                print("Signer \(index) failed")
                return nil
            }

            signatures.append(signature)
            print("Signer \(index) signed successfully")
        }

        print("Created \(signatures.count) signatures")

        return signatures
    }

    static func verifyMultiSignature(data: Data, signatures: [Data], publicKeys: [SecKey]) -> Int {
        print("\n--- Verify Multi-Signature ---")

        var validCount = 0

        for (index, signature) in signatures.enumerated() {
            guard index < publicKeys.count else {
                continue
            }

            var error: Unmanaged<CFError>?
            let isValid = SecKeyVerifySignature(
                publicKeys[index],
                .rsaSignatureDigestPKCS1v15SHA256,
                data as CFData,
                signature as CFData,
                &error
            )

            if isValid {
                validCount += 1
                print("Signature \(index) is valid")
            } else {
                print("Signature \(index) is invalid")
            }
        }

        print("Multi-signature valid: \(validCount)/\(signatures.count)")

        return validCount
    }
}

// 9. Blind Signature
class BlindSignature {

    // Simplified blind signature demonstration
    // Real blind signatures require complex cryptographic operations

    static func createBlindSignature(challenge: Data, using privateKey: SecKey) -> Data? {
        print("\n--- Create Blind Signature ---")

        // In a real implementation, the challenge would be blinded first
        // For demonstration, we just sign the challenge directly

        var error: Unmanaged<CFError>?
        guard let signature = SecKeyCreateSignature(
            privateKey,
            .rsaSignatureDigestPKCS1v15SHA256,
            challenge as CFData,
            &error
        ) as Data? else {
            print("Failed to create blind signature")
            return nil
        }

        print("Created blind signature (simplified)")

        return signature
    }
}

// 10. Signature Export/Import
class SignatureExport {

    static func exportSignature(_ signature: Data, format: SignatureFormat) -> String {
        print("\n--- Export Signature ---")

        let exported: String

        switch format {
        case .base64:
            exported = signature.base64EncodedString()
        case .hex:
            exported = signature.compactMap { String(format: "%02x", $0) }.joined()
        case .decimal:
            exported = signature.map { String($0) }.joined(separator: ",")
        }

        print("Exported signature (\(format)): \(exported.prefix(64))...)")

        return exported
    }

    static func importSignature(_ string: String, format: SignatureFormat) -> Data? {
        print("\n--- Import Signature ---")

        let data: Data?

        switch format {
        case .base64:
            data = Data(base64Encoded: string)
        case .hex:
            data = Data(hexString: string)
        case .decimal:
            let bytes = string.split(separator: ",").compactMap { UInt8($0) }
            data = Data(bytes)
        }

        if let signature = data {
            print("Imported signature (\(signature.count) bytes)")
        } else {
            print("Failed to import signature")
        }

        return data
    }

    enum SignatureFormat: String {
        case base64 = "Base64"
        case hex = "Hex"
        case decimal = "Decimal"
    }
}

// Main demonstration
func demonstrateDigitalSignatures() {
    print("=== macOS Swift Digital Signatures Examples ===")

    let testData = "Important message to sign".data(using: .utf8)!

    // RSA Signature
    if let rsaSigner = RSASignature(keySize: 2048) {
        if let rsaSig = rsaSigner.sign(data: testData) {
            _ = rsaSigner.verify(data: testData, signature: rsaSig)
        }

        if let rsaStringSig = rsaSigner.signString("Test string") {
            _ = rsaSigner.verifyString("Test string", signature: rsaStringSig)
        }
    }

    // ECDSA Signature
    let ecdsaSigner = ECDSASignature()
    if let ecdsaSig = ecdsaSigner.sign(data: testData) {
        _ = ecdsaSigner.verify(data: testData, signature: ecdsaSig)
    }

    // Ed25519 Signature
    let edSigner = Ed25519Signature()
    if let edSig = edSigner.sign(data: testData) {
        _ = edSigner.verify(data: testData, signature: edSig)
    }

    print("Public key: \(edSigner.exportPublicKey().prefix(32))...")

    // HMAC Signature
    let hmacKey = Data("secret_key".utf8)
    let hmacSig = HMACSignature.sign(key: hmacKey, message: testData)
    _ = HMACSignature.verify(key: hmacKey, message: testData, signature: hmacSig)

    // Detached Signature
    if let rsaSigner = RSASignature(keySize: 2048) {
        let detachedSig = DetachedSignature.createDetachedSignature(data: testData, using: rsaSigner.privateKey)
        if let sig = detachedSig {
            _ = DetachedSignature.verifyDetachedSignature(data: testData, signature: sig, publicKey: rsaSigner.publicKey)
        }
    }

    // Multi-signature
    if let signer1 = RSAKeyGeneration.generateKeyPair(keySize: 2048),
       let signer2 = RSAKeyGeneration.generateKeyPair(keySize: 2048) {
        let multiSigs = MultiSignature.createMultiSignature(data: testData, signers: [signer1.privateKey, signer2.privateKey])
        if let sigs = multiSigs {
            _ = MultiSignature.verifyMultiSignature(data: testData, signatures: sigs, publicKeys: [signer1.publicKey, signer2.publicKey])
        }
    }

    print("\n=== All Digital Signature Examples Completed ===")
}

// Run demonstration
demonstrateDigitalSignatures()