-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Encryption, Hashing, and expand Filesystem for better S3 support (#…
…85) An S3 / S3 compatible driver for Filesystem is in the alchemy-aws repo.
- Loading branch information
1 parent
70c07e1
commit 49f7e1a
Showing
32 changed files
with
554 additions
and
193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
@propertyWrapper | ||
public struct Encrypted: ModelProperty { | ||
public var wrappedValue: String | ||
|
||
// MARK: ModelProperty | ||
|
||
public init(key: String, on row: SQLRowReader) throws { | ||
let encrypted = try row.require(key).string() | ||
guard let data = Data(base64Encoded: encrypted) else { | ||
throw EncryptionError("could not decrypt data; it wasn't base64 encoded") | ||
} | ||
|
||
wrappedValue = try Crypt.decrypt(data: data) | ||
} | ||
|
||
public func store(key: String, on row: inout SQLRowWriter) throws { | ||
let encrypted = try Crypt.encrypt(string: wrappedValue) | ||
let string = encrypted.base64EncodedString() | ||
row.put(.string(string), at: key) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import Crypto | ||
import Foundation | ||
|
||
extension SymmetricKey { | ||
public static var app: SymmetricKey = { | ||
guard let appKey: String = Env.APP_KEY else { | ||
fatalError("Unable to load APP_KEY from Environment. Please set an APP_KEY before encrypting any data with `Crypt` or provide a custom `SymmetricKey` using `Crypt(key:)`.") | ||
} | ||
|
||
guard let data = Data(base64Encoded: appKey) else { | ||
fatalError("Unable to create encryption key from APP_KEY. Please ensure APP_KEY is a base64 encoded String.") | ||
} | ||
|
||
return SymmetricKey(data: data) | ||
}() | ||
} | ||
|
||
public struct Encrypter { | ||
private let key: SymmetricKey | ||
|
||
public init(key: SymmetricKey) { | ||
self.key = key | ||
} | ||
|
||
public func encrypt(string: String) throws -> Data { | ||
try encrypt(data: Data(string.utf8)) | ||
} | ||
|
||
public func encrypt<D: DataProtocol>(data: D) throws -> Data { | ||
guard let result = try AES.GCM.seal(data, using: key).combined else { | ||
throw EncryptionError("could not encrypt the data") | ||
} | ||
|
||
return result | ||
} | ||
|
||
public func decrypt(base64Encoded string: String) throws -> String { | ||
guard let data = Data(base64Encoded: string) else { | ||
throw EncryptionError("the string wasn't base64 encoded") | ||
} | ||
|
||
return try decrypt(data: data) | ||
} | ||
|
||
public func decrypt<D: DataProtocol>(data: D) throws -> String { | ||
let box = try AES.GCM.SealedBox(combined: data) | ||
let data = try AES.GCM.open(box, using: key) | ||
guard let string = String(data: data, encoding: .utf8) else { | ||
throw EncryptionError("could not decrypt the data") | ||
} | ||
|
||
return string | ||
} | ||
|
||
public static func generateKeyString(size: SymmetricKeySize = .bits256) -> String { | ||
SymmetricKey(size: size).withUnsafeBytes { Data($0) }.base64EncodedString() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
public struct EncryptionError: Error { | ||
public let message: String | ||
|
||
public init(_ message: String) { | ||
self.message = message | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.