Introduction
Basically, how/where do I persist encryption keys my executable needs?
Let me explain how my executable looks like. It's basically a Swift script that is compiled using swift build --configuration=release --product=App
.
Package.swift
:
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "App",
defaultLocalization: "en",
platforms: [
.macOS(.v10_15),
],
products: [
.executable(name: "App", targets: ["App"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.1"),
.package(url: "https://github.com/apple/swift-crypto", from: "2.0.0")
],
targets: [
.target(name: "App", dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "Crypto", package: "swift-crypto"),
]),
]
)
Some Ideas
- I know that Apple provides a Keychain on macOS to store keys. The problem is that my executable is not signed in any way, so it'd be difficult to enforce that only my executable can access the stored keys. (That's what I think at least, correct me if I'm wrong)
Git seems to somehow store user credentials in Keychain. How do they do it? Is their way even secure?
The next idea I had was to store the keys in the user's home directory, like
.ssh
. That seems insecure. As far as I know, any app running on the system could then read the keys, right?Another way to achieve this would be to encrypt the key using a password and then make the user enter their password every time the key is needed. This is the least preferable option because it is inconvenient.
The last option I thought of would be to sign my executable somehow. Is there any way to sign my executable so it can have it's own guarded space in the Keychain? What I need is a process to sign my executable without requiring an Apple Developer Account or any other central authority.
Question
How can I securely store encryption keys so only my executable (edit: and the user) can access them?