{"id":"5aec28ab-c985-47e9-981f-75230e8f860d","shortId":"uhZSHd","kind":"skill","title":"cryptokit","tagline":"Perform cryptographic operations using Apple CryptoKit. Use when hashing data with SHA256/SHA384/SHA512, generating HMAC authentication codes, encrypting with AES-GCM or ChaChaPoly, signing with P256/P384/P521/Curve25519 keys, performing ECDH key agreement, storing keys in the Se","description":"# CryptoKit\n\nApple CryptoKit provides a Swift-native API for cryptographic operations:\nhashing, message authentication, symmetric encryption, public-key signing,\nkey agreement, and Secure Enclave key storage. Available on iOS 13+.\nPrefer CryptoKit over CommonCrypto or raw Security framework APIs in all\nnew code targeting Swift 6.3+.\n\n## Contents\n\n- [Hashing](#hashing)\n- [HMAC](#hmac)\n- [Symmetric Encryption](#symmetric-encryption)\n- [Public-Key Signing](#public-key-signing)\n- [Key Agreement](#key-agreement)\n- [Secure Enclave](#secure-enclave)\n- [Common Mistakes](#common-mistakes)\n- [Review Checklist](#review-checklist)\n- [References](#references)\n\n## Hashing\n\nCryptoKit provides SHA256, SHA384, and SHA512 hash functions. All conform\nto the `HashFunction` protocol.\n\n### One-shot hashing\n\n```swift\nimport CryptoKit\n\nlet data = Data(\"Hello, world!\".utf8)\nlet digest = SHA256.hash(data: data)\nlet hex = digest.compactMap { String(format: \"%02x\", $0) }.joined()\n```\n\nSHA384 and SHA512 work identically -- substitute the type name.\n\n### Incremental hashing\n\nFor large data or streaming input, hash incrementally:\n\n```swift\nvar hasher = SHA256()\nhasher.update(data: chunk1)\nhasher.update(data: chunk2)\nlet digest = hasher.finalize()\n```\n\n### Digest comparison\n\nCryptoKit digests use constant-time comparison by default. Direct `==`\nchecks between digests are safe against timing attacks.\n\n```swift\nlet expected = SHA256.hash(data: reference)\nlet actual = SHA256.hash(data: received)\nif expected == actual {\n    // Data integrity verified\n}\n```\n\n## HMAC\n\nHMAC provides message authentication using a symmetric key and a hash function.\n\n### Computing an authentication code\n\n```swift\nlet key = SymmetricKey(size: .bits256)\nlet data = Data(\"message\".utf8)\n\nlet mac = HMAC<SHA256>.authenticationCode(for: data, using: key)\n```\n\n### Verifying an authentication code\n\n```swift\nlet isValid = HMAC<SHA256>.isValidAuthenticationCode(\n    mac, authenticating: data, using: key\n)\n```\n\nThis uses constant-time comparison internally.\n\n### Incremental HMAC\n\n```swift\nvar hmac = HMAC<SHA256>(key: key)\nhmac.update(data: chunk1)\nhmac.update(data: chunk2)\nlet mac = hmac.finalize()\n```\n\n## Symmetric Encryption\n\nCryptoKit provides two authenticated encryption ciphers: AES-GCM and\nChaChaPoly. Both produce a sealed box containing the nonce, ciphertext,\nand authentication tag.\n\n### AES-GCM\n\nThe default choice for symmetric encryption. Hardware-accelerated on Apple\nsilicon.\n\n```swift\nlet key = SymmetricKey(size: .bits256)\nlet plaintext = Data(\"Secret message\".utf8)\n\n// Encrypt\nlet sealedBox = try AES.GCM.seal(plaintext, using: key)\nlet ciphertext = sealedBox.combined!  // nonce + ciphertext + tag\n\n// Decrypt\nlet box = try AES.GCM.SealedBox(combined: ciphertext)\nlet decrypted = try AES.GCM.open(box, using: key)\n```\n\n### ChaChaPoly\n\nUse ChaChaPoly when AES hardware acceleration is unavailable or when\ninteroperating with protocols that require ChaCha20-Poly1305 (e.g., TLS,\nWireGuard).\n\n```swift\nlet sealedBox = try ChaChaPoly.seal(plaintext, using: key)\nlet combined = sealedBox.combined  // Always non-optional for ChaChaPoly\n\nlet box = try ChaChaPoly.SealedBox(combined: combined)\nlet decrypted = try ChaChaPoly.open(box, using: key)\n```\n\n### Authenticated data\n\nBoth ciphers support additional authenticated data (AAD). The AAD is\nauthenticated but not encrypted -- useful for metadata that must remain\nin the clear but be tamper-proof.\n\n```swift\nlet header = Data(\"v1\".utf8)\nlet sealedBox = try AES.GCM.seal(\n    plaintext, using: key, authenticating: header\n)\nlet decrypted = try AES.GCM.open(\n    sealedBox, using: key, authenticating: header\n)\n```\n\n### SymmetricKey sizes\n\n| Size | Use |\n|---|---|\n| `.bits128` | AES-128-GCM; adequate for most uses |\n| `.bits192` | AES-192-GCM; uncommon |\n| `.bits256` | AES-256-GCM or ChaChaPoly; recommended default |\n\n### Generating a key\n\n```swift\nlet key = SymmetricKey(size: .bits256)\n```\n\nTo create a key from existing data:\n\n```swift\nlet key = SymmetricKey(data: existingKeyData)\n```\n\n## Public-Key Signing\n\nCryptoKit supports ECDSA signing with NIST curves and Ed25519 via\nCurve25519.\n\n### NIST curves: P256, P384, P521\n\n```swift\nlet signingKey = P256.Signing.PrivateKey()\nlet publicKey = signingKey.publicKey\n\n// Sign\nlet signature = try signingKey.signature(for: data)\n\n// Verify\nlet isValid = publicKey.isValidSignature(signature, for: data)\n```\n\nP384 and P521 use the same API -- substitute the curve name.\n\nNIST key representations:\n\n```swift\n// Export\nlet der = signingKey.derRepresentation\nlet pem = signingKey.pemRepresentation\nlet x963 = signingKey.x963Representation\nlet raw = signingKey.rawRepresentation\n\n// Import\nlet restored = try P256.Signing.PrivateKey(derRepresentation: der)\n```\n\n### Curve25519 / Ed25519\n\n```swift\nlet signingKey = Curve25519.Signing.PrivateKey()\nlet publicKey = signingKey.publicKey\n\n// Sign\nlet signature = try signingKey.signature(for: data)\n\n// Verify\nlet isValid = publicKey.isValidSignature(signature, for: data)\n```\n\nCurve25519 keys use `rawRepresentation` only (no DER/PEM/X9.63).\n\n### Choosing a curve\n\n| Curve | Signature Scheme | Key Size | Typical Use |\n|---|---|---|---|\n| P256 | ECDSA | 256-bit | General purpose; Secure Enclave support |\n| P384 | ECDSA | 384-bit | Higher security requirements |\n| P521 | ECDSA | 521-bit | Maximum NIST security level |\n| Curve25519 | Ed25519 | 256-bit | Fast; simple API; no Secure Enclave |\n\nUse P256 by default. Use Curve25519 when interoperating with Ed25519-based\nprotocols.\n\n## Key Agreement\n\nKey agreement lets two parties derive a shared symmetric key from their\npublic/private key pairs using ECDH.\n\n### ECDH with P256\n\n```swift\n// Alice\nlet aliceKey = P256.KeyAgreement.PrivateKey()\n\n// Bob\nlet bobKey = P256.KeyAgreement.PrivateKey()\n\n// Alice computes shared secret\nlet sharedSecret = try aliceKey.sharedSecretFromKeyAgreement(\n    with: bobKey.publicKey\n)\n\n// Derive a symmetric key using HKDF\nlet symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(\n    using: SHA256.self,\n    salt: Data(\"salt\".utf8),\n    sharedInfo: Data(\"my-app-v1\".utf8),\n    outputByteCount: 32\n)\n```\n\nBob computes the same `sharedSecret` using his private key and Alice's\npublic key. Both derive the same `symmetricKey`.\n\n### ECDH with Curve25519\n\n```swift\nlet aliceKey = Curve25519.KeyAgreement.PrivateKey()\nlet bobKey = Curve25519.KeyAgreement.PrivateKey()\n\nlet sharedSecret = try aliceKey.sharedSecretFromKeyAgreement(\n    with: bobKey.publicKey\n)\n\nlet symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(\n    using: SHA256.self,\n    salt: Data(),\n    sharedInfo: Data(\"context\".utf8),\n    outputByteCount: 32\n)\n```\n\n### Key derivation functions\n\n`SharedSecret` is not directly usable as a `SymmetricKey`. Always derive\na key using one of:\n\n| Method | Standard | Use |\n|---|---|---|\n| `hkdfDerivedSymmetricKey` | HKDF (RFC 5869) | Recommended default |\n| `x963DerivedSymmetricKey` | ANSI X9.63 | Interop with X9.63 systems |\n\nAlways provide a non-empty `sharedInfo` string to bind the derived key\nto a specific protocol context.\n\n## Secure Enclave\n\nThe Secure Enclave provides hardware-backed key storage. Private keys\nnever leave the hardware. Only P256 signing and key agreement are\nsupported for ECDH operations. Post-quantum key types (MLKEM, MLDSA)\nare also available in the Secure Enclave on supported hardware.\n\n### Availability check\n\n```swift\nguard SecureEnclave.isAvailable else {\n    // Fall back to software keys\n    return\n}\n```\n\n### Creating a Secure Enclave signing key\n\n```swift\nlet privateKey = try SecureEnclave.P256.Signing.PrivateKey()\nlet publicKey = privateKey.publicKey  // Standard P256.Signing.PublicKey\n\nlet signature = try privateKey.signature(for: data)\nlet isValid = publicKey.isValidSignature(signature, for: data)\n```\n\n### Access control\n\nRequire biometric authentication to use the key:\n\n```swift\nlet accessControl = SecAccessControlCreateWithFlags(\n    nil,\n    kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,\n    [.privateKeyUsage, .biometryCurrentSet],\n    nil\n)!\n\nlet privateKey = try SecureEnclave.P256.Signing.PrivateKey(\n    accessControl: accessControl\n)\n```\n\n### Persisting Secure Enclave keys\n\nThe `dataRepresentation` is an encrypted blob that only the same device's\nSecure Enclave can restore. Store it in the Keychain.\n\n```swift\n// Export\nlet blob = privateKey.dataRepresentation\n\n// Restore\nlet restored = try SecureEnclave.P256.Signing.PrivateKey(\n    dataRepresentation: blob\n)\n```\n\n### Secure Enclave key agreement\n\n```swift\nlet seKey = try SecureEnclave.P256.KeyAgreement.PrivateKey()\nlet peerPublicKey: P256.KeyAgreement.PublicKey = // from peer\n\nlet sharedSecret = try seKey.sharedSecretFromKeyAgreement(\n    with: peerPublicKey\n)\n```\n\n## Common Mistakes\n\n### 1. Using the shared secret directly as a key\n\n```swift\n// DON'T\nlet badKey = SymmetricKey(data: sharedSecret)\n\n// DO -- derive with HKDF\nlet goodKey = sharedSecret.hkdfDerivedSymmetricKey(\n    using: SHA256.self,\n    salt: salt,\n    sharedInfo: info,\n    outputByteCount: 32\n)\n```\n\n### 2. Reusing nonces\n\n```swift\n// DON'T -- hardcoded nonce\nlet nonce = try AES.GCM.Nonce(data: Data(repeating: 0, count: 12))\nlet box = try AES.GCM.seal(data, using: key, nonce: nonce)\n\n// DO -- let CryptoKit generate a random nonce (default behavior)\nlet box = try AES.GCM.seal(data, using: key)\n```\n\n### 3. Ignoring authentication tag verification\n\n```swift\n// DON'T -- manually strip tag and decrypt\n// DO -- always use AES.GCM.open() or ChaChaPoly.open()\n// which verifies the tag automatically\n```\n\n### 4. Using Insecure hashes for security\n\n```swift\n// DON'T -- MD5/SHA1 for integrity or security\nimport CryptoKit\nlet bad = Insecure.MD5.hash(data: data)\n\n// DO -- use SHA256 or stronger\nlet good = SHA256.hash(data: data)\n```\n\n`Insecure.MD5` and `Insecure.SHA1` exist only for legacy compatibility\n(checksum verification, protocol interop). Never use them for new\nsecurity-sensitive operations.\n\n### 5. Storing symmetric keys in UserDefaults\n\n```swift\n// DON'T\nUserDefaults.standard.set(key.rawBytes, forKey: \"encryptionKey\")\n\n// DO -- store in Keychain\n// See references/cryptokit-patterns.md for Keychain storage patterns\n```\n\n### 6. Not checking Secure Enclave availability\n\n```swift\n// DON'T -- crash on simulator or unsupported hardware\nlet key = try SecureEnclave.P256.Signing.PrivateKey()\n\n// DO\nguard SecureEnclave.isAvailable else { /* fallback */ }\nlet key = try SecureEnclave.P256.Signing.PrivateKey()\n```\n\n## Review Checklist\n\n- [ ] Using CryptoKit, not CommonCrypto or raw Security framework\n- [ ] SHA256+ for hashing; no MD5/SHA1 for security purposes\n- [ ] HMAC verification uses `isValidAuthenticationCode` (constant-time)\n- [ ] AES-GCM or ChaChaPoly for symmetric encryption; 256-bit keys\n- [ ] Nonces are random (default) -- not hardcoded or reused\n- [ ] Authenticated data (AAD) used where metadata needs integrity\n- [ ] SharedSecret derived via HKDF, not used directly\n- [ ] sharedInfo parameter is non-empty and context-specific\n- [ ] Secure Enclave availability checked before use\n- [ ] Secure Enclave key `dataRepresentation` stored in Keychain\n- [ ] Private keys not logged, printed, or serialized unnecessarily\n- [ ] Symmetric keys stored in Keychain, not UserDefaults or files\n- [ ] Encryption export compliance considered (`ITSAppUsesNonExemptEncryption`)\n\n## References\n\n- Extended patterns (key serialization, Insecure module, Keychain integration, AES key wrapping, HPKE): [references/cryptokit-patterns.md](references/cryptokit-patterns.md)\n- Apple documentation: [CryptoKit](https://sosumi.ai/documentation/cryptokit)\n- Apple sample: [Performing Common Cryptographic Operations](https://sosumi.ai/documentation/cryptokit/performing-common-cryptographic-operations)\n- Apple sample: [Storing CryptoKit Keys in the Keychain](https://sosumi.ai/documentation/cryptokit/storing-cryptokit-keys-in-the-keychain)","tags":["cryptokit","swift","ios","skills","dpearson2699","accessibility","agent-skills","ai-coding","apple","claude-code","codex-skills","cursor-skills"],"capabilities":["skill","source-dpearson2699","skill-cryptokit","topic-accessibility","topic-agent-skills","topic-ai-coding","topic-apple","topic-claude-code","topic-codex-skills","topic-cursor-skills","topic-ios","topic-ios-development","topic-liquid-glass","topic-localization","topic-mapkit"],"categories":["swift-ios-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/dpearson2699/swift-ios-skills/cryptokit","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add dpearson2699/swift-ios-skills","source_repo":"https://github.com/dpearson2699/swift-ios-skills","install_from":"skills.sh"}},"qualityScore":"0.684","qualityRationale":"deterministic score 0.68 from registry signals: · indexed on github topic:agent-skills · 468 github stars · SKILL.md body (11,855 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T00:53:42.510Z","embedding":null,"createdAt":"2026-04-18T22:00:54.358Z","updatedAt":"2026-04-22T00:53:42.510Z","lastSeenAt":"2026-04-22T00:53:42.510Z","tsv":"'-128':502 '-192':510 '-256':515 '/documentation/cryptokit)':1365 '/documentation/cryptokit/performing-common-cryptographic-operations)':1374 '/documentation/cryptokit/storing-cryptokit-keys-in-the-keychain)':1385 '0':165,1086 '02x':164 '1':1039 '12':1088 '13':69 '2':1071 '256':661,685,1274 '3':1114 '32':770,818,1070 '384':670 '4':1138 '5':1190 '521':677 '5869':843 '6':1213 '6.3':85 'aad':450,452,1287 'acceler':346,396 'access':956 'accesscontrol':967,978,979 'actual':226,232 'addit':447 'adequ':504 'ae':21,319,336,394,501,509,514,1267,1354 'aes-gcm':20,318,335,1266 'aes.gcm.nonce':1082 'aes.gcm.open':386,490,1130 'aes.gcm.seal':366,481,1092,1110 'aes.gcm.sealedbox':380 'agreement':32,60,105,108,707,709,893,1020 'alic':729,737,781 'alicekey':731,795 'alicekey.sharedsecretfromkeyagreement':744,803 'also':907 'alway':423,830,853,1128 'ansi':847 'api':46,78,590,689 'app':766 'appl':6,39,348,1360,1366,1375 'attack':218 'authent':16,52,240,251,274,282,315,333,442,448,454,485,494,960,1116,1285 'authenticationcod':267 'automat':1137 'avail':66,908,916,1218,1312 'back':879,923 'bad':1155 'badkey':1052 'base':704 'behavior':1106 'bind':862 'biometr':959 'biometrycurrentset':972 'bit':662,671,678,686,1275 'bits128':500 'bits192':508 'bits256':258,355,513,529 'blob':989,1008,1016 'bob':733,771 'bobkey':735,798 'bobkey.publickey':746,805 'box':327,378,387,430,439,1090,1108 'chacha20':407 'chacha20-poly1305':406 'chachapoli':24,322,390,392,428,518,1270 'chachapoly.open':438,1132 'chachapoly.seal':416 'chachapoly.sealedbox':432 'check':211,917,1215,1313 'checklist':120,123,1242 'checksum':1177 'choic':340 'choos':649 'chunk1':192,303 'chunk2':195,306 'cipher':317,445 'ciphertext':331,371,374,382 'clear':466 'code':17,82,252,275 'combin':381,421,433,434 'common':114,117,1037,1369 'common-mistak':116 'commoncrypto':73,1246 'comparison':200,207,291 'compat':1176 'complianc':1342 'comput':249,738,772 'conform':136 'consid':1343 'constant':205,289,1264 'constant-tim':204,288,1263 'contain':328 'content':86 'context':815,870,1308 'context-specif':1307 'control':957 'count':1087 'crash':1222 'creat':531,928 'cryptograph':3,48,1370 'cryptokit':1,7,38,40,71,127,147,201,312,547,1100,1153,1244,1362,1378 'curv':553,559,593,651,652 'curve25519':557,619,642,683,698,792 'curve25519.keyagreement.privatekey':796,799 'curve25519.signing.privatekey':624 'data':11,149,150,157,158,180,191,194,223,228,233,260,261,269,283,302,305,358,443,449,475,536,541,576,583,634,641,759,763,812,814,949,955,1054,1083,1084,1093,1111,1157,1158,1167,1168,1286 'datarepresent':985,1015,1319 'decrypt':376,384,436,488,1126 'default':209,339,520,696,845,1105,1280 'der':601,618 'der/pem/x9.63':648 'deriv':713,747,786,820,831,864,1057,1294 'derrepresent':617 'devic':994 'digest':155,197,199,202,213 'digest.compactmap':161 'direct':210,825,1044,1299 'document':1361 'e.g':409 'ecdh':30,724,725,790,897 'ecdsa':549,660,669,676 'ed25519':555,620,684,703 'ed25519-based':702 'els':921,1235 'empti':858,1305 'enclav':63,110,113,666,692,872,875,912,931,982,997,1018,1217,1311,1317 'encrypt':18,54,92,95,311,316,343,362,457,988,1273,1340 'encryptionkey':1202 'exist':535,1172 'existingkeydata':542 'expect':221,231 'export':599,1006,1341 'extend':1346 'fall':922 'fallback':1236 'fast':687 'file':1339 'forkey':1201 'format':163 'framework':77,1250 'function':134,248,821 'gcm':22,320,337,503,511,516,1268 'general':663 'generat':14,521,1101 'good':1165 'goodkey':1061 'guard':919,1233 'hardcod':1077,1282 'hardwar':345,395,878,887,915,1227 'hardware-acceler':344 'hardware-back':877 'hash':10,50,87,88,126,133,144,177,184,247,1141,1253 'hasher':188 'hasher.finalize':198 'hasher.update':190,193 'hashfunct':139 'header':474,486,495 'hello':151 'hex':160 'higher':672 'hkdf':752,841,1059,1296 'hkdfderivedsymmetrickey':840 'hmac':15,89,90,236,237,266,279,294,297,298,1259 'hmac.finalize':309 'hmac.update':301,304 'hpke':1357 'ident':171 'ignor':1115 'import':146,612,1152 'increment':176,185,293 'info':1068 'input':183 'insecur':1140,1350 'insecure.md5':1169 'insecure.md5.hash':1156 'insecure.sha1':1171 'integr':234,1149,1292,1353 'intern':292 'interop':849,1180 'interoper':401,700 'io':68 'isvalid':278,579,637,951 'isvalidauthenticationcod':280,1262 'itsappusesnonexemptencrypt':1344 'join':166 'key':28,31,34,57,59,64,98,102,104,107,244,255,271,285,299,300,352,369,389,419,441,484,493,523,526,533,539,545,596,643,655,706,708,717,721,750,779,784,819,833,865,880,883,892,902,926,933,964,983,1019,1047,1095,1113,1193,1229,1238,1276,1318,1324,1332,1348,1355,1379 'key-agr':106 'key.rawbytes':1200 'keychain':1004,1206,1210,1322,1335,1352,1382 'ksecattraccessiblewhenpasscodesetthisdeviceon':970 'larg':179 'leav':885 'legaci':1175 'let':148,154,159,196,220,225,254,259,264,277,307,351,356,363,370,377,383,413,420,429,435,473,478,487,525,538,564,567,571,578,600,603,606,609,613,622,625,629,636,710,730,734,741,753,794,797,800,806,935,939,944,950,966,974,1007,1011,1022,1026,1031,1051,1060,1079,1089,1099,1107,1154,1164,1228,1237 'level':682 'log':1326 'mac':265,281,308 'manual':1122 'maximum':679 'md5/sha1':1147,1255 'messag':51,239,262,360 'metadata':460,1290 'method':837 'mistak':115,118,1038 'mldsa':905 'mlkem':904 'modul':1351 'must':462 'my-app-v1':764 'name':175,594 'nativ':45 'need':1291 'never':884,1181 'new':81,1185 'nil':969,973 'nist':552,558,595,680 'non':425,857,1304 'non-empti':856,1303 'non-opt':424 'nonc':330,373,1073,1078,1080,1096,1097,1104,1277 'one':142,835 'one-shot':141 'oper':4,49,898,1189,1371 'option':426 'outputbytecount':769,817,1069 'p256':560,659,694,727,889 'p256.keyagreement.privatekey':732,736 'p256.keyagreement.publickey':1028 'p256.signing.privatekey':566,616 'p256.signing.publickey':943 'p256/p384/p521/curve25519':27 'p384':561,584,668 'p521':562,586,675 'pair':722 'paramet':1301 'parti':712 'pattern':1212,1347 'peer':1030 'peerpublickey':1027,1036 'pem':604 'perform':2,29,1368 'persist':980 'plaintext':357,367,417,482 'poly1305':408 'post':900 'post-quantum':899 'prefer':70 'print':1327 'privat':778,882,1323 'privatekey':936,975 'privatekey.datarepresentation':1009 'privatekey.publickey':941 'privatekey.signature':947 'privatekeyusag':971 'produc':324 'proof':471 'protocol':140,403,705,869,1179 'provid':41,128,238,313,854,876 'public':56,97,101,544,783 'public-key':55,96,543 'public-key-sign':100 'public/private':720 'publickey':568,626,940 'publickey.isvalidsignature':580,638,952 'purpos':664,1258 'quantum':901 'random':1103,1279 'raw':75,610,1248 'rawrepresent':645 'receiv':229 'recommend':519,844 'refer':124,125,224,1345 'references/cryptokit-patterns.md':1208,1358,1359 'remain':463 'repeat':1085 'represent':597 'requir':405,674,958 'restor':614,999,1010,1012 'return':927 'reus':1072,1284 'review':119,122,1241 'review-checklist':121 'rfc':842 'safe':215 'salt':758,760,811,1065,1066 'sampl':1367,1376 'scheme':654 'se':37 'seal':326 'sealedbox':364,414,479,491 'sealedbox.combined':372,422 'secaccesscontrolcreatewithflag':968 'secret':359,740,1043 'secur':62,76,109,112,665,673,681,691,871,874,911,930,981,996,1017,1143,1151,1187,1216,1249,1257,1310,1316 'secure-enclav':111 'secureenclave.isavailable':920,1234 'secureenclave.p256.keyagreement.privatekey':1025 'secureenclave.p256.signing.privatekey':938,977,1014,1231,1240 'security-sensit':1186 'see':1207 'sekey':1023 'sekey.sharedsecretfromkeyagreement':1034 'sensit':1188 'serial':1329,1349 'sha256':129,189,1161,1251 'sha256.hash':156,222,227,1166 'sha256.self':757,810,1064 'sha256/sha384/sha512':13 'sha384':130,167 'sha512':132,169 'share':715,739,1042 'sharedinfo':762,813,859,1067,1300 'sharedsecret':742,775,801,822,1032,1055,1293 'sharedsecret.hkdfderivedsymmetrickey':755,808,1062 'shot':143 'sign':25,58,99,103,546,550,570,628,890,932 'signatur':572,581,630,639,653,945,953 'signingkey':565,623 'signingkey.derrepresentation':602 'signingkey.pemrepresentation':605 'signingkey.publickey':569,627 'signingkey.rawrepresentation':611 'signingkey.signature':574,632 'signingkey.x963representation':608 'silicon':349 'simpl':688 'simul':1224 'size':257,354,497,498,528,656 'skill' 'skill-cryptokit' 'softwar':925 'sosumi.ai':1364,1373,1384 'sosumi.ai/documentation/cryptokit)':1363 'sosumi.ai/documentation/cryptokit/performing-common-cryptographic-operations)':1372 'sosumi.ai/documentation/cryptokit/storing-cryptokit-keys-in-the-keychain)':1383 'source-dpearson2699' 'specif':868,1309 'standard':838,942 'storag':65,881,1211 'store':33,1000,1191,1204,1320,1333,1377 'stream':182 'string':162,860 'strip':1123 'stronger':1163 'substitut':172,591 'support':446,548,667,895,914 'swift':44,84,145,186,219,253,276,295,350,412,472,524,537,563,598,621,728,793,918,934,965,1005,1021,1048,1074,1119,1144,1196,1219 'swift-nat':43 'symmetr':53,91,94,243,310,342,716,749,1192,1272,1331 'symmetric-encrypt':93 'symmetrickey':256,353,496,527,540,754,789,807,829,1053 'system':852 'tag':334,375,1117,1124,1136 'tamper':470 'tamper-proof':469 'target':83 'time':206,217,290,1265 'tls':410 'topic-accessibility' 'topic-agent-skills' 'topic-ai-coding' 'topic-apple' 'topic-claude-code' 'topic-codex-skills' 'topic-cursor-skills' 'topic-ios' 'topic-ios-development' 'topic-liquid-glass' 'topic-localization' 'topic-mapkit' 'tri':365,379,385,415,431,437,480,489,573,615,631,743,802,937,946,976,1013,1024,1033,1081,1091,1109,1230,1239 'two':314,711 'type':174,903 'typic':657 'unavail':398 'uncommon':512 'unnecessarili':1330 'unsupport':1226 'usabl':826 'use':5,8,203,241,270,284,287,368,388,391,418,440,458,483,492,499,507,587,644,658,693,697,723,751,756,776,809,834,839,962,1040,1063,1094,1112,1129,1139,1160,1182,1243,1261,1288,1298,1315 'userdefault':1195,1337 'userdefaults.standard.set':1199 'utf8':153,263,361,477,761,768,816 'v1':476,767 'var':187,296 'verif':1118,1178,1260 'verifi':235,272,577,635,1134 'via':556,1295 'wireguard':411 'work':170 'world':152 'wrap':1356 'x9.63':848,851 'x963':607 'x963derivedsymmetrickey':846","prices":[{"id":"8ad54168-9a70-4352-b524-ba0dd68ba4e1","listingId":"5aec28ab-c985-47e9-981f-75230e8f860d","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"dpearson2699","category":"swift-ios-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:00:54.358Z"}],"sources":[{"listingId":"5aec28ab-c985-47e9-981f-75230e8f860d","source":"github","sourceId":"dpearson2699/swift-ios-skills/cryptokit","sourceUrl":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/cryptokit","isPrimary":false,"firstSeenAt":"2026-04-18T22:00:54.358Z","lastSeenAt":"2026-04-22T00:53:42.510Z"}],"details":{"listingId":"5aec28ab-c985-47e9-981f-75230e8f860d","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dpearson2699","slug":"cryptokit","github":{"repo":"dpearson2699/swift-ios-skills","stars":468,"topics":["accessibility","agent-skills","ai-coding","apple","claude-code","codex-skills","cursor-skills","ios","ios-development","liquid-glass","localization","mapkit","networking","storekit","swift","swift-concurrency","swiftdata","swiftui","widgetkit","xcode"],"license":"other","html_url":"https://github.com/dpearson2699/swift-ios-skills","pushed_at":"2026-04-21T19:26:16Z","description":"Agent Skills for iOS 26+, Swift 6.3, SwiftUI, and modern Apple frameworks","skill_md_sha":"8be9469f654ef1cc5c13d5419c22d921b3f9a467","skill_md_path":"skills/cryptokit/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/cryptokit"},"layout":"multi","source":"github","category":"swift-ios-skills","frontmatter":{"name":"cryptokit","description":"Perform cryptographic operations using Apple CryptoKit. Use when hashing data with SHA256/SHA384/SHA512, generating HMAC authentication codes, encrypting with AES-GCM or ChaChaPoly, signing with P256/P384/P521/Curve25519 keys, performing ECDH key agreement, storing keys in the Secure Enclave, or migrating from CommonCrypto to CryptoKit."},"skills_sh_url":"https://skills.sh/dpearson2699/swift-ios-skills/cryptokit"},"updatedAt":"2026-04-22T00:53:42.510Z"}}