All open-source packages
ToolingSwift

iOSSecurityTools

Keychain, encryption, pinning, one-time codes and integrity checks for Apple apps.

5StarsLatest Release: v2.1.0 · Updated: October 21, 2026
Platforms:iOS 17macOS 14tvOS 17watchOS 10visionOS 1

License: MIT

Tests: 589Measured:

How it was measured

swift test at PR #25 head 5b71c19 (the planned v2.1.0, not yet tagged) on macOS 27.0.1, Apple Swift 6.4: "Test run with 589 tests in 101 suites passed after 370.336 seconds". Re-run at the v2.1.0 tag before publishing.

Summary

  • A dependency-free Swift package of keychain, encryption, Secure Enclave, pinning, one-time password, integrity and log redaction building blocks for five Apple platforms.
  • The 2.0.0 log redactor could be bypassed with look-alike letters, escapes and secret names written as values, so 2.0.0 should not be relied on for logs.
  • In 2.1.0 only plain-ASCII keys are compared with the secret names, and the value under any other key is hidden by default.
  • JSON, form and multipart bodies are read with parsers, and a body that does not parse completely or is over 256 KiB is omitted.
  • Redaction is a safety net against secrets logged by accident, not a guarantee against someone who disguises a secret on purpose.

A Swift package of security building blocks for apps on iOS, macOS, tvOS, watchOS and visionOS: keychain storage, authenticated encryption, PIN hashes, Secure Enclave keys, certificate pinning, one-time passwords, device integrity checks and log redaction. Each type validates what it is given and throws a typed error instead of crashing, so values from a QR code, a server or a file cannot trap the app. It calls Apple's frameworks directly and has no dependencies.

Features

  • Keychain stores data, strings and Codable values, creates 256-bit keys on first use and can require Face ID, Touch ID or the passcode, enforced by the keychain itself
  • DataCipher writes AES-256-GCM or ChaCha20-Poly1305 envelopes with their own version, algorithm and nonce; a changed byte, a wrong key or wrong associated data fails decryption
  • HKDF, PBKDF2 and PHC-format PIN hashes, with iteration counts capped so a tampered hash cannot make verification run for hours
  • PinningPolicy requires a backup pin, supports subdomains, expiration dates and a report-only mode, and still requires the system's own trust evaluation to pass
  • HOTP and TOTP with otpauth:// parsing and writing, and Secure Enclave P-256 keys for binding an account to the device
  • IntegrityInspector reports jailbreak files, a debugger, the simulator, hooking libraries and a system proxy as signals in a Codable report, not as proof
  • SensitiveDataRedactor compares only plain-ASCII keys with its secret names and hides the value of every other key; JSON, form and multipart bodies and URLs are read with parsers, and what cannot be parsed is omitted
  • @Redacted prints <redacted> in descriptions, and .privacyShield() covers views in the app switcher and during screen recording

Quickstart

swift
1import SwiftUI
2import iOSSecurityTools
3 
4struct ContentView: View {
5 @State private var status = "Nothing stored yet"
6 
7 var body: some View {
8 VStack(spacing: 16) {
9 Text(status)
10 Button("Encrypt and store a note") {
11 do {
12 let keychain = Keychain(service: "QuickStart")
13 let cipher = try DataCipher(key: keychain.symmetricKey(forKey: "notes-key"))
14 try keychain.set(cipher.encrypt("Meet at 7 pm"), forKey: "note")
15 
16 let stored = try keychain.data(forKey: "note") ?? Data()
17 status = "Decrypted: \(try cipher.decryptString(stored))"
18 } catch {
19 status = error.localizedDescription
20 }
21 }
22 .buttonStyle(.borderedProminent)
23 }
24 .padding()
25 .privacyShield()
26 }
27}

Installation

Swift Package Manager

swift
1dependencies: [
2 .package(url: "https://github.com/muhittincamdali/iOSSecurityTools.git", from: "2.1.0")
3],
4targets: [
5 .target(name: "YourApp", dependencies: [
6 .product(name: "iOSSecurityTools", package: "iOSSecurityTools")
7 ])
8]

Xcode

text
1https://github.com/muhittincamdali/iOSSecurityTools.git

Screenshots

A log text with an email, a password, a bearer token and a card number, and the redacted version below it
A log text with an email, a password, a bearer token and a card number, and the redacted version below it, dark mode
A note encrypted into the keychain as 46 bytes and read back, and a PIN checked against its stored hash
Integrity report in the simulator: jailbreak check not applicable, simulator found, debugger, injected libraries and proxy clear
A six-digit TOTP code from an otpauth URI with a ring counting down the seconds left
A card details view covered by the privacy shield with a lock symbol

Timeline

  1. Repository opened with AES and RSA encryption helpers

  2. v1.0.0 released, a different code base from the current package

  3. Cleanup: the 1.0.0 sources were replaced with placeholder code

  4. Rebuilt from scratch as 2.0.0: keychain, encryption, Secure Enclave keys, biometrics, pinning, one-time passwords, integrity checks and log redaction; no 1.0.0 API kept

  5. 2.1.0: the log redactor was redesigned after 2.0.0 was shown to be bypassable; keys that are not plain ASCII are hidden by default, and bodies and URLs are read with parsers

Links

Related Article

Read the article