[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-6707":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":22,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":37,"readmeContent":38,"aiSummary":39,"trendingCount":16,"starSnapshotCount":16,"syncStatus":40,"lastSyncTime":41,"discoverSource":42},6707,"CryptoSwift","krzyzanowskim\u002FCryptoSwift","krzyzanowskim","CryptoSwift is a growing collection of standard and secure cryptographic algorithms implemented in Swift","http:\u002F\u002Fcryptoswift.io",null,"Swift",10555,1799,181,4,0,13,71.07,"Other",false,"main",true,[24,25,26,27,28,29,30,31,32,33,34,35,36],"aes","aes-gcm","cipher","commoncrypto","cryptography","cryptoswift","digest","hmac","hmac-authentication","md5","sha1","sha3","swift","2026-06-12 04:00:30","[![Platform](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FPlatforms-Apple%20platforms%20%7C%20Linux%20%7C%20Android-4E4E4E.svg?colorA=28a745)](#requirements)\n\n[![Swift support](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FSwift-5.6%2B-lightgrey.svg?colorA=28a745&colorB=4E4E4E)](#requirements)\n[![Swift Package Manager compatible](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FSPM-compatible-brightgreen.svg?style=flat&colorA=28a745&&colorB=4E4E4E)](https:\u002F\u002Fgithub.com\u002Fswiftlang\u002Fswift-package-manager)\n[![Carthage compatible](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCarthage-compatible-brightgreen.svg?style=flat&colorA=28a745&&colorB=4E4E4E)](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage)\n[![CocoaPods Deprecated](https:\u002F\u002Fimg.shields.io\u002Fcocoapods\u002Fv\u002FCryptoSwift.svg?style=flat&label=CocoaPods&colorA=red&&colorB=4E4E4E)](https:\u002F\u002Fcocoapods.org\u002Fpods\u002FCryptoSwift)\n\n# CryptoSwift\n\nPure Swift cryptographic primitives and utilities for [Swift](https:\u002F\u002Fswift.org). ([#PureSwift](https:\u002F\u002Ftwitter.com\u002Fhashtag\u002Fpureswift))\n\n**Note**: The current release line builds with Swift 5.6 and newer toolchains. If you need an older compiler, use the matching legacy branch listed in [Swift version support](#swift-version-support). Older branches are not actively maintained.\n\n---\n\n[Requirements](#requirements) | [Features](#features) | [Recommended Defaults](#recommended-defaults) | [Contribution](#contribution) | [Installation](#installation) | [Swift Version Support](#swift-version-support) | [How-to](#how-to) | [Author](#author) | [License](#license) | [Changelog](#changelog)\n\n### Support & Sponsors\n\nThe financial sustainability of the project is possible thanks to the ongoing contributions from our [GitHub Sponsors](https:\u002F\u002Fgithub.com\u002Fsponsors\u002Fkrzyzanowskim)\n\n### Premium Sponsors\n\nNone\n\n## Requirements\n\nGood mood\n\n- Swift 5.6 or newer\n- Apple deployment targets: iOS 11, macOS 10.13, Mac Catalyst 13, tvOS 11, watchOS 4, visionOS 1\n- Linux and Android are exercised in CI\n\n## Features\n\n- Pure Swift implementation\n- Convenient extensions for `String`, `Data`, and `Array\u003CUInt8>`\n- Support for incremental updates and streaming APIs\n- Apple platforms, Linux, and Android support\n\n#### Hash (Digest)\n  [MD5](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc1321)\n| [SHA1](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc3174)\n| [SHA2-224](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc6234)\n| [SHA2-256](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc6234)\n| [SHA2-384](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc6234)\n| [SHA2-512](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc6234)\n| [SHA3](https:\u002F\u002Fnvlpubs.nist.gov\u002Fnistpubs\u002FFIPS\u002FNIST.FIPS.202.pdf)\n\n#### Cyclic Redundancy Check (CRC)\n  [CRC32](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCyclic_redundancy_check)\n| [CRC32C](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCyclic_redundancy_check)\n| [CRC16](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCyclic_redundancy_check)\n\n#### Cipher\n  [AES-128, AES-192, AES-256](http:\u002F\u002Fcsrc.nist.gov\u002Fpublications\u002Ffips\u002Ffips197\u002Ffips-197.pdf)\n| [ChaCha20](http:\u002F\u002Fcr.yp.to\u002Fchacha\u002Fchacha-20080128.pdf)\n| [XChaCha20](https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fhtml\u002Fdraft-irtf-cfrg-xchacha)\n| [Rabbit](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc4503)\n| [Blowfish](https:\u002F\u002Fwww.schneier.com\u002Facademic\u002Fblowfish\u002F)\n\n#### RSA (public-key encryption algorithm)\n  [Encryption, Signature](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift#rsa)\n\n#### Message authenticators\n  [Poly1305](https:\u002F\u002Fcr.yp.to\u002Fmac\u002Fpoly1305-20050329.pdf)\n| [HMAC (MD5, SHA1, SHA256)](https:\u002F\u002Fwww.ietf.org\u002Frfc\u002Frfc2104.txt)\n| [CMAC](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc4493)\n| [CBC-MAC](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCBC-MAC)\n\n#### Cipher mode of operation\n- Electronic codebook ([ECB](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBlock_cipher_mode_of_operation#Electronic_codebook_.28ECB.29))\n- Cipher-block chaining ([CBC](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBlock_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29))\n- Propagating Cipher Block Chaining ([PCBC](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBlock_cipher_mode_of_operation#Propagating_Cipher_Block_Chaining_.28PCBC.29))\n- Cipher feedback ([CFB](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBlock_cipher_mode_of_operation#Cipher_feedback_.28CFB.29))\n- Output Feedback ([OFB](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBlock_cipher_mode_of_operation#Output_Feedback_.28OFB.29))\n- Counter Mode ([CTR](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBlock_cipher_mode_of_operation#Counter_.28CTR.29))\n- Galois\u002FCounter Mode ([GCM](https:\u002F\u002Fcsrc.nist.gov\u002Fpublications\u002Fdetail\u002Fsp\u002F800-38d\u002Ffinal))\n- Counter with Cipher Block Chaining-Message Authentication Code ([CCM](https:\u002F\u002Fcsrc.nist.gov\u002Fpublications\u002Fdetail\u002Fsp\u002F800-38c\u002Ffinal))\n- OCB Authenticated-Encryption Algorithm ([OCB](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc7253))\n\n#### Password-Based Key Derivation Function\n- [PBKDF1](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc2898#section-5.1) (Password-Based Key Derivation Function 1)\n- [PBKDF2](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc2898#section-5.2) (Password-Based Key Derivation Function 2)\n- [HKDF](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc5869) (HMAC-based Extract-and-Expand Key Derivation Function)\n- [Scrypt](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc7914) (The scrypt Password-Based Key Derivation Function)\n\n#### Data padding\n- [PKCS#5](https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc2898.html)\n- [EMSA-PKCS1-v1_5 (Encoding Method for Signature)](https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc3447#section-9.2)\n- [EME-PKCS1-v1_5 (Encoding Method for Encryption)](https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc3447)\n- [PKCS#7](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc5652#section-6.3)\n- [Zero padding](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPadding_(cryptography)#Zero_padding)\n- [ISO\u002FIEC 7816-4](https:\u002F\u002Fwww.embedx.com\u002Fpdfs\u002FISO_STD_7816\u002Finfo_isoiec7816-4%7Bed21.0%7Den.pdf)\n- [ISO10126](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPadding_(cryptography)#ISO_10126)\n- No padding\n\n#### Authenticated Encryption with Associated Data (AEAD)\n- [AEAD\\_CHACHA20\\_POLY1305](https:\u002F\u002Ftools.ietf.org\u002Fhtml\u002Frfc7539#section-2.8)\n- [AEAD\\_XCHACHA20\\_POLY1305](https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fhtml\u002Fdraft-irtf-cfrg-xchacha#section-2)\n\n## Recommended Defaults\n\n- Prefer AEAD constructions such as AES-GCM, AES-CCM, ChaCha20-Poly1305, or XChaCha20-Poly1305 for new protocols.\n- Prefer SHA-256, SHA-512, or SHA-3 over MD5 and SHA-1.\n- Use a fresh IV or nonce for every encryption operation.\n- Use RSA keys of at least 2048 bits for new systems.\n- Treat MD5, SHA-1, ECB, CBC-MAC, and PKCS#1 v1.5 compatibility paths as legacy interoperability features.\n\n## Why\n[Why?](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Fdiscussions\u002F982) [Because I can](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Fdiscussions\u002F982#discussioncomment-3669415).\n\n## How do I get involved?\n\nYou want to help, great! Go ahead and fork our repo, make your changes and send us a pull request.\n\n## Contribution\n\nCheck out [CONTRIBUTING.md](CONTRIBUTING.md) for more information on how to help with CryptoSwift.\n\n- If you found a bug, [open a discussion](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Fdiscussions).\n- If you have a feature request, [open a discussion](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Fdiscussions).\n\n## Installation\n\n### Swift Package Manager\n\nCryptoSwift is primarily distributed as source through [Swift Package Manager](https:\u002F\u002Fswift.org\u002Fpackage-manager\u002F).\n\nAdd the package dependency:\n\n```swift\ndependencies: [\n  .package(url: \"https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift.git\", from: \"1.10.0\")\n]\n```\n\nThen add the product to the target that uses it:\n\n```swift\n.target(\n  name: \"MyTarget\",\n  dependencies: [\n    .product(name: \"CryptoSwift\", package: \"CryptoSwift\")\n  ]\n)\n```\n\nIf you profile crypto-heavy workloads from Xcode, compare Debug and Release builds before drawing conclusions. Debug builds can be dramatically slower than optimized Release builds.\n\n### XCFramework\n\nIf you prefer a prebuilt optimized binary for manual Xcode integration, build `CryptoSwift.xcframework` locally:\n\n```sh\n.\u002Fscripts\u002Fbuild-framework.sh\n```\n\nThe generated `CryptoSwift.xcframework` is an alternative to source-based Swift Package Manager integration. It is not used by the package defined in [Package.swift](Package.swift).\n\n\u003Cimg width=\"320\" alt=\"Screen Shot 2020-10-27 at 00 06 32\" src=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F758033\u002F97240586-f0878280-17ee-11eb-9119-e5a960417d04.png\">\n\n### Hardened Runtime (macOS) and Xcode\n\nIf you embed the prebuilt `CryptoSwift.xcframework` in a hardened macOS app, library validation can prevent the binary from loading when the app is signed with `Sign to Run Locally`.\n\nTo avoid that, use one of these options:\n- Sign the app with a proper Development certificate.\n- Enable `Disable Library Validation` (`com.apple.security.cs.disable-library-validation`) for the app.\n\n### Xcode Project\n\nTo vendor CryptoSwift directly in an Xcode project, add it as a submodule from the top-level project directory:\n\n```sh\ngit submodule add https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift.git\n```\n\nEnable [Whole-Module Optimization](https:\u002F\u002Fswift.org\u002Fblog\u002Fwhole-module-optimizations\u002F) for best performance. Non-optimized builds of crypto-heavy code are significantly slower.\n\n### Legacy Package Managers\n\n#### Carthage\n\nYou can use [Carthage](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage) for existing projects.\nSpecify in `Cartfile`:\n\n```ruby\ngithub \"krzyzanowskim\u002FCryptoSwift\"\n```\n\nRun `carthage` to build the framework and drag the built `CryptoSwift.framework` into your Xcode project. Follow the [Carthage getting started guide](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage#getting-started). See [common issues](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Fdiscussions\u002F983#discussioncomment-3669433) if the build fails.\n\n#### CocoaPods\n\n> **Note**: CocoaPods is deprecated for new CryptoSwift integrations. Prefer Swift Package Manager. Keep CocoaPods only when you need it for an existing project.\n\nYou can still use [CocoaPods](https:\u002F\u002Fcocoapods.org\u002Fpods\u002FCryptoSwift).\n\n```ruby\npod 'CryptoSwift', '~> 1.10.0'\n```\n\nCocoaPods builds may need manual optimization settings if performance matters. You can adjust them after installation, or use the [cocoapods-wholemodule](https:\u002F\u002Fgithub.com\u002Fjedlewison\u002Fcocoapods-wholemodule) plugin.\n\n### Embedded Framework\n\nEmbedded frameworks require a minimum deployment target of iOS 11.0 or macOS 10.13. Drag `CryptoSwift.xcodeproj` into your Xcode project, add the appropriate framework as a dependency, then embed `CryptoSwift.framework` in your app target.\n\n![](https:\u002F\u002Fcloud.githubusercontent.com\u002Fassets\u002F758033\u002F10834511\u002F25a26852-7e9a-11e5-8c01-6cc8f1838459.png)\n\nSometimes the embedded framework option is not available automatically. In that case, add a new build phase for the target.\n\n![](https:\u002F\u002Fcloud.githubusercontent.com\u002Fassets\u002F758033\u002F18415615\u002Fd5edabb0-77f8-11e6-8c94-f41d9fc2b8cb.png)\n\n#### iOS, macOS, watchOS, tvOS\n\nIn the project, you'll find [single scheme](https:\u002F\u002Fmxcl.dev\u002FPromiseKit\u002Fnews\u002F2016\u002F08\u002FMultiplatform-Single-Scheme-Xcode-Projects\u002F) for all platforms:\n- CryptoSwift\n\n### Swift Version Support\n\n- Current release line: Swift 5.6 and newer toolchains\n\nLegacy compiler branches:\n\n- Swift 1.2: branch [swift12](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift12) version \u003C= 0.0.13\n- Swift 2.1: branch [swift21](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift21) version \u003C= 0.2.3\n- Swift 2.2, 2.3: branch [swift2](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift2) version \u003C= 0.5.2\n- Swift 3.1, branch [swift3](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift3) version \u003C= 0.6.9\n- Swift 3.2, branch [swift32](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift32) version = 0.7.0\n- Swift 4.0, branch [swift4](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift4) version \u003C= 0.12.0\n- Swift 4.2, branch [swift42](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift42) version \u003C= 0.15.0\n- Swift 5.0, branch [swift5](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift5) version \u003C= 1.2.0\n- Swift 5.1, branch [swift51](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift51) version \u003C= 1.3.3\n- Swift 5.3, branch [swift53](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fswift53) version \u003C= 1.8.5\n- Swift 5.6 and newer, branch [main](https:\u002F\u002Fgithub.com\u002Fkrzyzanowskim\u002FCryptoSwift\u002Ftree\u002Fmain)\n\n## How-to\n\n* [Basics (data types, conversion, ...)](#basics)\n* [Digest (MD5, SHA...)](#calculate-digest)\n* [Message authenticators (HMAC, CMAC...)](#message-authenticators-1)\n* [Password-Based Key Derivation Function (PBKDF2, ...)](#password-based-key-derivation-functions)\n* [HMAC-based Key Derivation Function (HKDF)](#hmac-based-key-derivation-function)\n* [Data Padding](#data-padding)\n* [AEAD (ChaCha20-Poly1305)](#aead)\n* [AES-GCM](#aes-gcm)\n* [AES-CCM](#aes-ccm)\n* [AES - Advanced Encryption Standard](#aes)\n* [ChaCha20](#chacha20)\n* [Rabbit](#rabbit)\n* [Blowfish](#blowfish)\n* [RSA](#rsa)\n\nFor new designs, start with an AEAD construction such as AES-GCM, AES-CCM, or ChaCha20-Poly1305. Use raw block modes only when you need compatibility with an existing protocol.\n\n##### Basics\n\n```swift\nimport CryptoSwift\n```\n\nCryptoSwift uses array of bytes aka `Array\u003CUInt8>` as a base type for all operations. Every data may be converted to a stream of bytes. You will find convenience functions that accept `String` or `Data`, and it will be internally converted to the array of bytes.\n\n##### Data types conversion\n\nFor your convenience, **CryptoSwift** provides two functions to easily convert an array of bytes to `Data` or `Data` to an array of bytes:\n\nData from bytes:\n\n```swift\nlet data = Data([0x01, 0x02, 0x03])\n```\n\n`Data` to `Array\u003CUInt8>`\n\n```swift\nlet bytes = data.byteArray                \u002F\u002F [1,2,3]\n```\n\n[Hexadecimal](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHexadecimal) encoding:\n\n```swift\nlet bytes = Array\u003CUInt8>(hex: \"0x010203\")  \u002F\u002F [1,2,3]\nlet hex   = bytes.toHexString()            \u002F\u002F \"010203\"\n```\n\nBuild bytes out of `String`\n```swift\nlet bytes: Array\u003CUInt8> = \"cipherkey\".bytes  \u002F\u002F Array(\"cipherkey\".utf8)\n```\n\nAlso... check out helpers that work with **Base64** encoded data:\n```swift\n\"aPf\u002Fi9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=\".decryptBase64ToString(cipher)\n\"aPf\u002Fi9th9iX+vf49eR7PYk2q7S5xmm3jkRLejgzHNJs=\".decryptBase64(cipher)\nbytes.toBase64()\n```\n\n##### Calculate Digest\n\nHashing an array of bytes (`Array\u003CUInt8>`)\n```swift\nlet input: Array\u003CUInt8> = [0x01, 0x02, 0x03]\n\nlet md5Digest = input.md5()\nlet md5Digest2 = Digest.md5(input)\n```\n\nHashing `Data`\n\n```swift\nlet data = Data([0x01, 0x02, 0x03])\n\nlet md5Digest = data.md5()\nlet sha1Digest = data.sha1()\nlet sha224Digest = data.sha224()\nlet sha256Digest = data.sha256()\nlet sha384Digest = data.sha384()\nlet sha512Digest = data.sha512()\n```\n```swift\ndo {\n    var digest = MD5()\n    _ = try digest.update(withBytes: [0x31, 0x32])\n    _ = try digest.update(withBytes: [0x33])\n    let result = try digest.finish()\n} catch {\n    print(error)\n}\n```\n\nHashing a String and printing result\n\n```swift\nlet hash = \"123\".md5() \u002F\u002F \"123\".bytes.md5()\n```\n\n##### Calculate CRC\n\n```swift\nlet bytes: Array\u003CUInt8> = [0x01, 0x02, 0x03]\nlet data = Data(bytes)\n\nlet bytesCRC16 = bytes.crc16()\nlet dataCRC16 = data.crc16()\n\nlet bytesCRC32 = bytes.crc32()\nlet dataCRC32 = data.crc32()\n```\n\n##### Message authenticators\n\n```swift\n\u002F\u002F Calculate Message Authentication Code (MAC) for message\nlet key = Array\u003CUInt8>(repeating: 0x01, count: 32)\nlet message = Array(\"authenticated message\".utf8)\n\nlet poly1305 = try Poly1305(key: key).authenticate(message)\nlet hmac = try HMAC(key: key, variant: .sha2(.sha256)).authenticate(message)\nlet cmac = try CMAC(key: key).authenticate(message)\n```\n\n##### Password-Based Key Derivation Functions\n\n```swift\nlet password: Array\u003CUInt8> = Array(\"s33krit\".utf8)\nlet salt: Array\u003CUInt8> = Array(\"nacllcan\".utf8)\n\nlet key = try PKCS5.PBKDF2(password: password, salt: salt, iterations: 4096, keyLength: 32, variant: .sha2(.sha256)).calculate()\n```\n\n```swift\nlet password: Array\u003CUInt8> = Array(\"s33krit\".utf8)\nlet salt: Array\u003CUInt8> = Array(\"nacllcan\".utf8)\n\u002F\u002F Scrypt implementation does not implement work parallelization, so `p` parameter will\n\u002F\u002F increase the work time even in multicore systems\nlet key = try Scrypt(password: password, salt: salt, dkLen: 64, N: 16384, r: 8, p: 1).calculate()\n```\n\n##### HMAC-based Key Derivation Function\n\n```swift\nlet password: Array\u003CUInt8> = Array(\"s33krit\".utf8)\nlet salt: Array\u003CUInt8> = Array(\"nacllcan\".utf8)\n\nlet key = try HKDF(password: password, salt: salt, variant: .sha2(.sha256)).calculate()\n```\n\n\n##### Data Padding\n\nSome content-encryption algorithms assume the input length is a multiple of `k` octets, where `k` is greater than one. For such algorithms, the input shall be padded.\n\n```swift\nlet input = Array(\"hello\".utf8)\nlet padded = Padding.pkcs7.add(to: input, blockSize: AES.blockSize)\n```\n\n#### Working with Ciphers\n\nExamples below use `[UInt8]` keys, IVs or nonces, and messages of the correct length for the selected algorithm.\n##### ChaCha20\n\n```swift\nlet encrypted = try ChaCha20(key: key, iv: iv).encrypt(message)\nlet decrypted = try ChaCha20(key: key, iv: iv).decrypt(encrypted)\n```\n\n##### Rabbit\n\n```swift\nlet encrypted = try Rabbit(key: key, iv: iv).encrypt(message)\nlet decrypted = try Rabbit(key: key, iv: iv).decrypt(encrypted)\n```\n##### Blowfish\n\n```swift\nlet encrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(message)\nlet decrypted = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted)\n```\n\n##### AES\n\nFor new designs, prefer AES-GCM unless you need compatibility with an existing CBC, CFB, OFB, or CTR protocol.\n\nNotice regarding padding: *Manual padding of data is optional, and CryptoSwift uses PKCS7 padding by default. If you need to manually disable or enable padding, configure the `AES` initializer explicitly.*\n\nVariant of AES encryption (AES-128, AES-192, AES-256) depends on given key length:\n\n- AES-128 = 16 bytes\n- AES-192 = 24 bytes\n- AES-256 = 32 bytes\n\nAES-256 example\n\n```swift\nlet aes = try AES(key: [1,2,3 \u002F* ... 32 bytes total *\u002F], blockMode: CBC(iv: [1,2,3 \u002F* ... 16 bytes total *\u002F]), padding: .pkcs7)\nlet encryptedBytes = try aes.encrypt(Array(\"secret message\".utf8))\n```\n\nFull example:\n\n```swift\nlet password: [UInt8] = Array(\"s33krit\".utf8)\nlet salt: [UInt8] = Array(\"nacllcan\".utf8)\n\n\u002F* Generate a key from a `password`. Optional if you already have a key *\u002F\nlet key = try PKCS5.PBKDF2(\n    password: password,\n    salt: salt,\n    iterations: 4096,\n    keyLength: 32, \u002F* AES-256 *\u002F\n    variant: .sha2(.sha256)\n).calculate()\n\n\u002F* Generate random IV value. IV is public value. Either need to generate, or get it from elsewhere *\u002F\nlet iv = AES.randomIV(AES.blockSize)\n\n\u002F* AES cryptor instance *\u002F\nlet aes = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7)\n\n\u002F* Encrypt Data *\u002F\nlet inputData = Data()\nlet encryptedBytes = try aes.encrypt(inputData.byteArray)\nlet encryptedData = Data(encryptedBytes)\n\n\u002F* Decrypt Data *\u002F\nlet decryptedBytes = try aes.decrypt(encryptedData.byteArray)\nlet decryptedData = Data(decryptedBytes)\n```\n\n###### All at once\n```swift\ndo {\n    let aes = try AES(key: \"keykeykeykeykeyk\", iv: \"drowssapdrowssap\") \u002F\u002F aes128\n    let ciphertext = try aes.encrypt(Array(\"Nullam quis risus eget urna mollis ornare vel eu leo.\".utf8))\n} catch { }\n```\n\n###### Incremental updates\n\nIncremental operations use instance of Cryptor and encrypt\u002Fdecrypt one part at a time, this way you can save on memory for large files.\n\n```swift\ndo {\n    var encryptor = try AES(key: \"keykeykeykeykeyk\", iv: \"drowssapdrowssap\").makeEncryptor()\n\n    var ciphertext = Array\u003CUInt8>()\n    \u002F\u002F aggregate partial results\n    ciphertext += try encryptor.update(withBytes: Array(\"Nullam quis risus \".utf8))\n    ciphertext += try encryptor.update(withBytes: Array(\"eget urna mollis \".utf8))\n    ciphertext += try encryptor.update(withBytes: Array(\"ornare vel eu leo.\".utf8))\n    \u002F\u002F finish at the end\n    ciphertext += try encryptor.finish()\n\n    print(ciphertext.toHexString())\n} catch {\n    print(error)\n}\n```\n\n###### AES Advanced usage\n```swift\nlet input: Array\u003CUInt8> = [0,1,2,3,4,5,6,7,8,9]\n\nlet key: Array\u003CUInt8> = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]\nlet iv: Array\u003CUInt8> = [] \u002F\u002F Random bytes of `AES.blockSize` length\n\ndo {\n    let encrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(input)\n    let decrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted)\n} catch {\n    print(error)\n}\n```\n\nAES without data padding\n\n```swift\nlet input: Array\u003CUInt8> = [0,1,2,3,4,5,6,7,8,9]\nlet encrypted: Array\u003CUInt8> = try! AES(key: Array(\"secret0key000000\".utf8), blockMode: CBC(iv: Array(\"0123456789012345\".utf8)), padding: .noPadding).encrypt(input)\n```\n\nUsing convenience extensions\n\n```swift\nlet plain = Data([0x01, 0x02, 0x03])\nlet encrypted = try! plain.encrypt(ChaCha20(key: key, iv: iv))\nlet decrypted = try! encrypted.decrypt(ChaCha20(key: key, iv: iv))\n```\n\n##### AES-GCM\n\nThe result of Galois\u002FCounter Mode (GCM) encryption is ciphertext and **authentication tag**, which is later used for decryption.\n\nencryption\n\n```swift\ndo {\n    \u002F\u002F In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want.\n    let gcm = GCM(iv: iv, mode: .combined)\n    let aes = try AES(key: key, blockMode: gcm, padding: .noPadding)\n    let encrypted = try aes.encrypt(plaintext)\n    let tag = gcm.authenticationTag\n} catch {\n    \u002F\u002F failed\n}\n```\n\ndecryption\n\n```swift\ndo {\n    \u002F\u002F In combined mode, the authentication tag is appended to the encrypted message. This is usually what you want.\n    let gcm = GCM(iv: iv, mode: .combined)\n    let aes = try AES(key: key, blockMode: gcm, padding: .noPadding)\n    let decrypted = try aes.decrypt(encrypted)\n} catch {\n    \u002F\u002F failed\n}\n```\n\n**Note**: GCM instance is not intended to be reused. So you can't use the same `GCM` instance from encoding to also perform decoding.\n\n##### AES-CCM\n\nThe result of Counter with Cipher Block Chaining-Message Authentication Code encryption is ciphertext and **authentication tag**, which is later used for decryption.\n\n```swift\ndo {\n    \u002F\u002F `encrypted` contains ciphertext with the authentication tag appended.\n\tlet tagLength = 8\n\tlet ccm = CCM(iv: iv, tagLength: tagLength, messageLength: encrypted.count - tagLength, additionalAuthenticatedData: data)\n    let aes = try AES(key: key, blockMode: ccm, padding: .noPadding)\n    let decrypted = try aes.decrypt(encrypted)\n} catch {\n    \u002F\u002F failed\n}\n```\n\nCheck documentation or CCM specification for valid parameters for CCM.\n\n##### AEAD\n\n```swift\nlet sealed = try AEADChaCha20Poly1305.encrypt(plaintext, key: key, iv: nonce, authenticationHeader: header)\nlet opened = try AEADChaCha20Poly1305.decrypt(\n  sealed.cipherText,\n  key: key,\n  iv: nonce,\n  authenticationHeader: header,\n  authenticationTag: sealed.authenticationTag\n)\n```\n\n##### RSA\n\nRSA initialization from parameters\n\n```swift\nlet input: Array\u003CUInt8> = [0,1,2,3,4,5,6,7,8,9]\n\nlet n: Array\u003CUInt8> = [] \u002F\u002F RSA modulus\nlet e: Array\u003CUInt8> = [] \u002F\u002F RSA public exponent\nlet d: Array\u003CUInt8> = [] \u002F\u002F RSA private exponent\n\nlet rsa = RSA(n: n, e: e, d: d)\n\ndo {\n    let encrypted = try rsa.encrypt(input)\n    let decrypted = try rsa.decrypt(encrypted)\n} catch {\n    print(error)\n}\n```\n\nRSA key generation\n\n```swift\nlet rsa = try RSA(keySize: 2048) \u002F\u002F This generates a modulus, public exponent and private exponent with the given size\n```\n\nRSA Encryption & Decryption Example\n``` swift\n\u002F\u002F Alice Generates a Private Key\nlet alicesPrivateKey = try RSA(keySize: 2048)\n    \n\u002F\u002F Alice shares her **public** key with Bob\nlet alicesPublicKeyData = try alicesPrivateKey.publicKeyExternalRepresentation()\n    \n\u002F\u002F Bob receives the raw external representation of Alice's public key and imports it\nlet bobsImportOfAlicesPublicKey = try RSA(rawRepresentation: alicesPublicKeyData)\n    \n\u002F\u002F Bob can now encrypt a message for Alice using her public key\nlet message = \"Hi Alice! This is Bob!\"\nlet privateMessage = try bobsImportOfAlicesPublicKey.encrypt(message.bytes)\n    \n\u002F\u002F This results in some encrypted output like this\n\u002F\u002F URcRwG6LfH63zOQf2w+HIllPri9Rb6hFlXbi\u002Fbh03zPl2MIIiSTjbAPqbVFmoF3RmDzFjIarIS7ZpT57a1F+OFOJjx50WYlng7dioKFS\u002FrsuGHYnMn4csjCRF6TAqvRQcRnBueeINRRA8SLaLHX6sZuQkjIE5AoHJwgavmiv8PY=\n      \n\u002F\u002F Bob can now send this encrypted message to Alice without worrying about people being able to read the original contents\n    \n\u002F\u002F Alice receives the encrypted message and uses her private key to decrypt the data and recover the original message\nlet originalDecryptedMessage = try alicesPrivateKey.decrypt(privateMessage)\n    \nprint(String(data: Data(originalDecryptedMessage), encoding: .utf8))\n\u002F\u002F \"Hi Alice! This is Bob!\"\n```\n\nRSA Signature & Verification Example\n``` swift\n\u002F\u002F Alice Generates a Private Key\nlet alicesPrivateKey = try RSA(keySize: 2048)\n    \n\u002F\u002F Alice wants to sign a message that she agrees with\nlet messageAliceSupports = \"Hi my name is Alice!\"\nlet alicesSignature = try alicesPrivateKey.sign(messageAliceSupports.bytes)\n    \n\u002F\u002F Alice shares her Public key and the signature with Bob\nlet alicesPublicKeyData = try alicesPrivateKey.publicKeyExternalRepresentation()\n    \n\u002F\u002F Bob receives the raw external representation of Alice's public key and imports it!\nlet bobsImportOfAlicesPublicKey = try RSA(rawRepresentation: alicesPublicKeyData)\n        \n\u002F\u002F Bob can now verify that Alice signed the message using the Private key associated with her shared Public key.\nlet verifiedSignature = try bobsImportOfAlicesPublicKey.verify(signature: alicesSignature, for: \"Hi my name is Alice!\".bytes)\n    \nif verifiedSignature == true {\n  \u002F\u002F 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.\n} else {\n  \u002F\u002F The signature was invalid, so either\n  \u002F\u002F - the message Alice signed was different than what we expected.\n  \u002F\u002F - or Alice used a Private key that isn't associated with the shared Public key that Bob has.\n}\n```\n\nThese `SecKey` interoperability examples are available on Apple platforms only.\n\nCryptoSwift RSA Key -> Apple's Security Framework SecKey Example\n``` swift\n\u002F\u002F\u002F Starting with a CryptoSwift RSA Key\nlet rsaKey = try RSA(keySize: 2048)\n\n\u002F\u002F\u002F Define your Keys attributes\nlet attributes: [String:Any] = [\n  kSecAttrKeyType as String: kSecAttrKeyTypeRSA,\n  kSecAttrKeyClass as String: kSecAttrKeyClassPrivate, \u002F\u002F or kSecAttrKeyClassPublic\n  kSecAttrKeySizeInBits as String: 2048, \u002F\u002F The appropriate bits\n  kSecAttrIsPermanent as String: false\n]\nvar error:Unmanaged\u003CCFError>? = nil\nguard let rsaSecKey = try SecKeyCreateWithData(rsaKey.externalRepresentation() as CFData, attributes as CFDictionary, &error) else {\n  \u002F\u002F\u002F Error constructing SecKey from raw key data\n  return\n}\n\n\u002F\u002F\u002F You now have an RSA SecKey for use with Apple's Security framework\n```\n\nApple's Security Framework SecKey -> CryptoSwift RSA Key Example\n``` swift\n\u002F\u002F\u002F Starting with a SecKey RSA Key\nlet rsaSecKey:SecKey\n\n\u002F\u002F\u002F Copy External Representation\nvar externalRepError:Unmanaged\u003CCFError>?\nguard let cfdata = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) else {\n  \u002F\u002F\u002F Failed to copy external representation for RSA SecKey\n  return\n}\n\n\u002F\u002F\u002F Instantiate the RSA Key from the raw external representation\nlet rsaKey = try RSA(rawRepresentation: cfdata as Data)\n\n\u002F\u002F\u002F You now have a CryptoSwift RSA Key\n```\n\n\n## Author\n\nCryptoSwift is owned and maintained by [Marcin Krzyżanowski](https:\u002F\u002Fwww.krzyzanowskim.com)\n\nYou can follow me on Twitter at [@krzyzanowskim](https:\u002F\u002Fx.com\u002Fkrzyzanowskim) for project updates and releases.\n\n# Cryptography Notice\n\nThis distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and\u002For re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See https:\u002F\u002Fwww.wassenaar.org\u002F for more information.\n\n## License\n\nCopyright (C) 2014-2025 Marcin Krzyżanowski \u003Cmarcin@krzyzanowskim.com>\nThis software is provided 'as-is', without any express or implied warranty.\n\nIn no event will the authors be held liable for any damages arising from the use of this software.\n\nPermission 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:\n\n- 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**.\n- Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n- This notice may not be removed or altered from any source or binary distribution.\n- Redistributions of any form whatsoever must retain the following acknowledgment: 'This product includes software developed by the \"Marcin Krzyzanowski\" (https:\u002F\u002Fkrzyzanowskim.com\u002F).'\n\n## Changelog\n\nSee [CHANGELOG](.\u002FCHANGELOG) file.\n","CryptoSwift 是一个用 Swift 编写的加密算法库，提供了多种标准且安全的加密功能。它支持 AES、ChaCha20、SHA 系列等常见的加密和哈希算法，并为 `String`、`Data` 和 `Array\u003CUInt8>` 提供了便捷的扩展方法。此外，该库还支持流式 API 和增量更新，适用于需要在 Apple 平台（iOS 11 及以上版本）、Linux 或 Android 上进行加密处理的应用场景。由于其纯 Swift 实现的特点，CryptoSwift 不仅易于集成到 Swift 项目中，还能通过 Swift Package Manager 或 Carthage 进行管理。",2,"2026-06-11 03:08:25","top_language"]