) {
29 | // Called when the user discards a scene session.
30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
32 | }
33 |
34 |
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/Placeholder.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Placeholder.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/Placeholder.imageset/Placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mehrankmlf/SecurityKit/8c2a2ae2b4f057c3007b667bf9dea65bc3f967ce/Example/Example/Assets.xcassets/Placeholder.imageset/Placeholder.png
--------------------------------------------------------------------------------
/Example/Example/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Example/Example/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
36 |
42 |
43 |
44 |
45 |
46 |
47 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
70 |
76 |
77 |
78 |
79 |
80 |
81 |
87 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/Example/Example/BaseViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseViewController.swift
3 | // Example
4 | //
5 | // Created by Mehran on 5/6/1401 AP.
6 | //
7 |
8 | import UIKit
9 |
10 | class BaseViewController: UIViewController {
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 |
15 | // Do any additional setup after loading the view.
16 | }
17 |
18 | func showAlert(message : String) {
19 | // create the alert
20 | let alert = UIAlertController(title: "Alert", message: message, preferredStyle: .alert)
21 |
22 | // add an action (button)
23 | alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
24 |
25 | // show the alert
26 | self.present(alert, animated: true, completion: nil)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Example/Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIApplicationSceneManifest
6 |
7 | UIApplicationSupportsMultipleScenes
8 |
9 | UISceneConfigurations
10 |
11 | UIWindowSceneSessionRoleApplication
12 |
13 |
14 | UISceneConfigurationName
15 | Default Configuration
16 | UISceneDelegateClassName
17 | $(PRODUCT_MODULE_NAME).SceneDelegate
18 | UISceneStoryboardFile
19 | Main
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Example/Example/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // Example
4 | //
5 | // Created by Mehran on 4/24/1401 AP.
6 | //
7 |
8 | import UIKit
9 | import SecurityKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | SecurityKit.removeSecureScreenShot(window: &window)
34 | }
35 |
36 | func sceneWillResignActive(_ scene: UIScene) {
37 | // Called when the scene will move from an active state to an inactive state.
38 | // This may occur due to temporary interruptions (ex. an incoming phone call).
39 | guard let image = UIImage(named: "Placeholder") else {return}
40 | SecurityKit.createSecureScreenShot(window: window, image: image)
41 | }
42 |
43 | func sceneWillEnterForeground(_ scene: UIScene) {
44 | // Called as the scene transitions from the background to the foreground.
45 | // Use this method to undo the changes made on entering the background.
46 | }
47 |
48 | func sceneDidEnterBackground(_ scene: UIScene) {
49 | // Called as the scene transitions from the foreground to the background.
50 | // Use this method to save data, release shared resources, and store enough scene-specific state information
51 | // to restore the scene back to its current state.
52 | }
53 |
54 |
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/Example/Example/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Example
4 | //
5 | // Created by Mehran on 4/24/1401 AP.
6 | //
7 |
8 | import UIKit
9 | import SecurityKit
10 |
11 | class ViewController: BaseViewController {
12 |
13 | @IBOutlet weak var lblJailBroken: UILabel!
14 | @IBOutlet weak var lblReverseEngineering: UILabel!
15 | @IBOutlet weak var lblDeviceisSimulator: UILabel!
16 | @IBOutlet weak var lblVPNActivate: UILabel!
17 |
18 | override func viewDidLoad() {
19 | super.viewDidLoad()
20 | self.checkJailBrokenDevice()
21 | self.checkReverseEngineering()
22 | self.checkSimulator()
23 | self.checkVPNActivate()
24 |
25 | ScreenCaptureProtection.shared.makeProtection(for: self.view)
26 |
27 | self.makaStringObfuscate()
28 | }
29 |
30 | private func checkJailBrokenDevice() {
31 | if SecurityKit.isDeviceJailBroken() {
32 | lblJailBroken.text = "YES"
33 | }else{
34 | lblJailBroken.text = "NO"
35 | }
36 | }
37 |
38 | private func checkReverseEngineering() {
39 | if SecurityKit.isReverseEngineeringToolsExecuted() {
40 | lblReverseEngineering.text = "YES"
41 | }else{
42 | lblReverseEngineering.text = "NO"
43 | }
44 | }
45 |
46 | private func checkSimulator() {
47 | if SecurityKit.isDeviceSimulator() {
48 | lblDeviceisSimulator.text = "YES"
49 | }else{
50 | lblDeviceisSimulator.text = "NO"
51 | }
52 | }
53 |
54 | private func checkVPNActivate() {
55 | if SecurityKit.isVPNConnected() {
56 | lblVPNActivate.text = "YES"
57 | }else{
58 | lblVPNActivate.text = "NO"
59 | }
60 | }
61 |
62 | private func makaStringObfuscate() {
63 | let plainText = "PlainText"
64 | let key = "key"
65 |
66 | let encrypt = SecurityKit.stringEncryption(plainText: plainText, encryptionKey: key)
67 |
68 | print(encrypt)
69 |
70 | let decrypt = SecurityKit.stringDecryption(cypherText: encrypt, decryptionKey: key)
71 |
72 | print(decrypt)
73 | }
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/Example/ExampleTests/ExampleTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleTests.swift
3 | // ExampleTests
4 | //
5 | // Created by Mehran on 4/24/1401 AP.
6 | //
7 |
8 | import XCTest
9 | @testable import Example
10 |
11 | class ExampleTests: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 | }
16 |
17 | override func tearDownWithError() throws {
18 | // Put teardown code here. This method is called after the invocation of each test method in the class.
19 | }
20 |
21 | func testExample() throws {
22 | // This is an example of a functional test case.
23 | // Use XCTAssert and related functions to verify your tests produce the correct results.
24 | // Any test you write for XCTest can be annotated as throws and async.
25 | // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
26 | // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
27 | }
28 |
29 | func testPerformanceExample() throws {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Example/ExampleUITests/ExampleUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleUITests.swift
3 | // ExampleUITests
4 | //
5 | // Created by Mehran on 4/24/1401 AP.
6 | //
7 |
8 | import XCTest
9 |
10 | class ExampleUITests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 |
15 | // In UI tests it is usually best to stop immediately when a failure occurs.
16 | continueAfterFailure = false
17 |
18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
19 | }
20 |
21 | override func tearDownWithError() throws {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | func testExample() throws {
26 | // UI tests must launch the application that they test.
27 | let app = XCUIApplication()
28 | app.launch()
29 |
30 | // Use XCTAssert and related functions to verify your tests produce the correct results.
31 | }
32 |
33 | func testLaunchPerformance() throws {
34 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
35 | // This measures how long it takes to launch your application.
36 | measure(metrics: [XCTApplicationLaunchMetric()]) {
37 | XCUIApplication().launch()
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Example/ExampleUITests/ExampleUITestsLaunchTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleUITestsLaunchTests.swift
3 | // ExampleUITests
4 | //
5 | // Created by Mehran on 4/24/1401 AP.
6 | //
7 |
8 | import XCTest
9 |
10 | class ExampleUITestsLaunchTests: XCTestCase {
11 |
12 | override class var runsForEachTargetApplicationUIConfiguration: Bool {
13 | true
14 | }
15 |
16 | override func setUpWithError() throws {
17 | continueAfterFailure = false
18 | }
19 |
20 | func testLaunch() throws {
21 | let app = XCUIApplication()
22 | app.launch()
23 |
24 | // Insert steps here to perform after app launch but before taking a screenshot,
25 | // such as logging into a test account or navigating somewhere in the app
26 |
27 | let attachment = XCTAttachment(screenshot: app.screenshot())
28 | attachment.name = "Launch Screen"
29 | attachment.lifetime = .keepAlways
30 | add(attachment)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'Example' do
5 | # Comment the next line if you don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | # Pods for Example
9 |
10 | pod 'SecurityKit', :path => '../'
11 |
12 | target 'ExampleTests' do
13 | inherit! :search_paths
14 | # Pods for testing
15 | end
16 |
17 | target 'ExampleUITests' do
18 | # Pods for testing
19 | end
20 |
21 | end
22 |
--------------------------------------------------------------------------------
/Example/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - SecurityKit (1.0.3)
3 |
4 | DEPENDENCIES:
5 | - SecurityKit (from `../`)
6 |
7 | EXTERNAL SOURCES:
8 | SecurityKit:
9 | :path: "../"
10 |
11 | SPEC CHECKSUMS:
12 | SecurityKit: 85ef0d59759701b5cfe111ed23f3f45071974cc5
13 |
14 | PODFILE CHECKSUM: 1d02dc804be3aff50268d847013a14a3783a604e
15 |
16 | COCOAPODS: 1.12.0
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Mehran Kamalifard
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Mehran Kamalifard
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.7
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | // Package.swift
5 | // SecurityKit
6 | //
7 | // Created by Steven Woolgar on 04/02/2023.
8 | // Copyright © 2023 Mehran Kamalifard. All rights reserved.
9 | //
10 |
11 | import PackageDescription
12 |
13 | let package = Package(
14 | name: "SecurityKit",
15 | defaultLocalization: "en",
16 | platforms: [.iOS(.v12)],
17 |
18 | products: [.library(name: "SecurityKit", targets: ["SecurityKit"])],
19 | targets: [
20 | .target(
21 | name: "SecurityKit",
22 | path: "SecurityKit/SecurityKit",
23 | exclude: ["SecurityKit.docc"]
24 | )
25 | ],
26 |
27 | swiftLanguageVersions: [.v5]
28 | )
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ## Security Kit
6 |
7 |
8 |
9 | Security Kit is a lightweight framework that helps to achieve a security layer
10 |
11 |
12 |
13 |
14 | • Example
15 | • Usage
16 | • Installation
17 | • License
18 |
19 |
20 | ## Example
21 |
22 | To run the example project, run `pod try SecurityKit`
23 |
24 | ## Features
25 |
26 | - [x] JailBroken Device Detection
27 | - [x] Security Background Layer
28 | - [x] Detect Reverse Engineering Tools Executed.
29 | - [x] Check Device is a Simulator or a Real Device.
30 | - [x] Check VPN is running.
31 | - [x] Screen Capture Protection.
32 | - [x] Obfuscate Sensitive String with XOR Data Encryption Algorithm.
33 |
34 | ### Requirements
35 |
36 | | Language | Branch | Pod version | Xcode version | iOS version |
37 | | --------- | ------ | ----------- | ------------- | ----------- |
38 | | Swift 5.0 | [master](https://github.com/mehrankmlf/SecurityKit/tree/master) | >= 1.0.x | Xcode 10+ | iOS 12.0+ |
39 |
40 | ### CocoaPods
41 |
42 | [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:
43 |
44 | ```bash
45 | $ gem install cocoapods
46 | ```
47 |
48 | To integrate SecurityKit into your Xcode project using CocoaPods, specify it in your `Podfile`:
49 |
50 | ```ruby
51 | source 'https://github.com/CocoaPods/Specs.git'
52 | platform :ios, '11.0'
53 | use_frameworks!
54 |
55 | target '' do
56 | pod 'SecurityKit'
57 | end
58 | ```
59 |
60 | Then, run the following command:
61 |
62 | ```bash
63 | $ pod install
64 | ```
65 | ## Installation
66 |
67 | ### CocoaPods
68 |
69 | ```ruby
70 | pod 'SecurityKit'
71 | ```
72 |
73 | ## Usage
74 |
75 | ## JailBroken Device Deteaction
76 |
77 | ```swift
78 |
79 | import SecurityKit
80 |
81 | if SecurityKit.isDeviceJailBroken() {
82 | // Do Something
83 | }else{
84 | // Do Something
85 | }
86 |
87 | ```
88 |
89 | ### Check Device is Simulator
90 |
91 | ```swift
92 |
93 | import SecurityKit
94 |
95 | if SecurityKit.isDeviceSimulator() {
96 | // Do Something
97 | }else{
98 | // Do Something
99 | }
100 |
101 | ```
102 |
103 | ### Reverse Engineering Tools
104 |
105 | ```swift
106 |
107 | import SecurityKit
108 |
109 | if SecurityKit.isRevereseEngineeringToolsExecuted() {
110 | // Do Something
111 | }else{
112 | // Do Something
113 | }
114 |
115 | ```
116 |
117 | ### Check VPN Runs
118 |
119 | ```swift
120 |
121 | import SecurityKit
122 |
123 | if SecurityKit.isVPNConnected() {
124 | // Do Something
125 | }else{
126 | // Do Something
127 | }
128 |
129 | ```
130 |
131 | ### Security Screen Capture
132 |
133 | ```swift
134 |
135 | import SecurityKit
136 |
137 | override func viewDidLoad() {
138 | super.viewDidLoad()
139 | ScreenCaptureProtection.shared.makeProtection(for: self.view)
140 | }
141 |
142 | override func viewWillAppear(_ animated: Bool) {
143 | super.viewWillAppear(false)
144 | ScreenCaptureProtection.shared.removeScreenProtection(for: self.view)
145 | }
146 |
147 | ```
148 |
149 | ### Security Background Layer
150 |
151 | ```swift
152 |
153 | import SecurityKit
154 |
155 | var window: UIWindow?
156 |
157 | func sceneWillResignActive(_ scene: UIScene) {
158 | // Called when the scene will move from an active state to an inactive state.
159 | // This may occur due to temporary interruptions (ex. an incoming phone call).
160 |
161 | guard let image = UIImage(named: "Placeholder") else {return}
162 | SecurityKit.createSecureScreenShot(window: window, image: image)
163 | }
164 |
165 | func sceneDidBecomeActive(_ scene: UIScene) {
166 | // Called when the scene has moved from an inactive state to an active state.
167 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
168 |
169 | SecurityKit.removeSecureScreenShot(window: &window)
170 | }
171 |
172 | ```
173 |
174 | ### XOR String obfuscation
175 |
176 | ```swift
177 |
178 | import SecurityKit
179 |
180 | // String Encryption
181 | let encrypt = SecurityKit.stringEncryption(plainText: "plainText", encryptionKey: "key")
182 |
183 | // String Decryption
184 | let decrypt = SecurityKit.stringDecryption(cypherText: encrypt, decryptionKey: key)
185 |
186 | ```
187 | ## License
188 |
189 | SecurityKit is available under the MIT license. See the [LICENSE](LICENSE) file for more info.
190 |
--------------------------------------------------------------------------------
/Resource/TopImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mehrankmlf/SecurityKit/8c2a2ae2b4f057c3007b667bf9dea65bc3f967ce/Resource/TopImage.png
--------------------------------------------------------------------------------
/SecurityKit.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |spec|
2 |
3 | spec.name = "SecurityKit"
4 | spec.version = "1.0.3"
5 | spec.summary = "SecurityKit is a security framework for iOS."
6 | # spec.description = "SecurityKit is a security framework for iOS."
7 |
8 | spec.homepage = "https://github.com/mehrankmlf/SecurityKit"
9 |
10 | spec.license = "MIT"
11 |
12 |
13 | spec.author = { "Mehran Kamalifard" => "mehran.kmlf@icloud.com" }
14 | spec.social_media_url = "https://www.linkedin.com/in/mehran-kamalifard/"
15 |
16 | spec.platform = :ios, "12.0"
17 |
18 | spec.source = { :git => "https://github.com/mehrankmlf/SecurityKit.git", :tag => spec.version.to_s }
19 |
20 | spec.source_files = "SecurityKit/SecurityKit/*.{h,m,swift}"
21 | spec.swift_version = "5.0"
22 |
23 | end
24 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 55;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 0203EAF728661D9300A2E7A2 /* SecurityKit.docc in Sources */ = {isa = PBXBuildFile; fileRef = 0203EAF628661D9300A2E7A2 /* SecurityKit.docc */; };
11 | 0203EAFD28661D9300A2E7A2 /* SecurityKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0203EAF228661D9300A2E7A2 /* SecurityKit.framework */; };
12 | 0203EB0328661D9300A2E7A2 /* SecurityKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0203EAF528661D9300A2E7A2 /* SecurityKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
13 | 0203EB0D28661F8D00A2E7A2 /* JailBrokenDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0203EB0C28661F8D00A2E7A2 /* JailBrokenDetection.swift */; };
14 | 0219951D286A0F73001830A2 /* BackgroundLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0219951C286A0F73001830A2 /* BackgroundLayer.swift */; };
15 | 02341F6F28C7AE94001E05C5 /* StringEncryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02341F6E28C7AE94001E05C5 /* StringEncryption.swift */; };
16 | 0234CA7A28CB744800AC66A3 /* StringEncryptionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0234CA7928CB744800AC66A3 /* StringEncryptionTest.swift */; };
17 | 0234CA8128CB8CD500AC66A3 /* TestableStringEncryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0234CA7E28CB84F800AC66A3 /* TestableStringEncryption.swift */; };
18 | 023E1CF0286ED94100061EB4 /* SecurityKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023E1CEF286ED94100061EB4 /* SecurityKit.swift */; };
19 | 0247D85A2868B07200D57EFE /* SimulatorDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0247D8592868B07200D57EFE /* SimulatorDetection.swift */; };
20 | 0247D85C2868BE4100D57EFE /* ReverseEngineering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0247D85B2868BE4100D57EFE /* ReverseEngineering.swift */; };
21 | 025683C8289AD7570029BC78 /* ScreenCaptureProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 025683C7289AD7570029BC78 /* ScreenCaptureProtection.swift */; };
22 | 02E953CF2868DD35002929FF /* VPNChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02E953CE2868DD35002929FF /* VPNChecker.swift */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXContainerItemProxy section */
26 | 0203EAFE28661D9300A2E7A2 /* PBXContainerItemProxy */ = {
27 | isa = PBXContainerItemProxy;
28 | containerPortal = 0203EAE928661D9300A2E7A2 /* Project object */;
29 | proxyType = 1;
30 | remoteGlobalIDString = 0203EAF128661D9300A2E7A2;
31 | remoteInfo = SecurityKit;
32 | };
33 | /* End PBXContainerItemProxy section */
34 |
35 | /* Begin PBXFileReference section */
36 | 0203EAF228661D9300A2E7A2 /* SecurityKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SecurityKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
37 | 0203EAF528661D9300A2E7A2 /* SecurityKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecurityKit.h; sourceTree = ""; };
38 | 0203EAF628661D9300A2E7A2 /* SecurityKit.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = SecurityKit.docc; sourceTree = ""; };
39 | 0203EAFC28661D9300A2E7A2 /* SecurityKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecurityKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
40 | 0203EB0C28661F8D00A2E7A2 /* JailBrokenDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JailBrokenDetection.swift; sourceTree = ""; };
41 | 0219951C286A0F73001830A2 /* BackgroundLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundLayer.swift; sourceTree = ""; };
42 | 02341F6E28C7AE94001E05C5 /* StringEncryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringEncryption.swift; sourceTree = ""; };
43 | 0234CA7928CB744800AC66A3 /* StringEncryptionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringEncryptionTest.swift; sourceTree = ""; };
44 | 0234CA7E28CB84F800AC66A3 /* TestableStringEncryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableStringEncryption.swift; sourceTree = ""; };
45 | 023E1CEF286ED94100061EB4 /* SecurityKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityKit.swift; sourceTree = ""; };
46 | 0247D8592868B07200D57EFE /* SimulatorDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorDetection.swift; sourceTree = ""; };
47 | 0247D85B2868BE4100D57EFE /* ReverseEngineering.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReverseEngineering.swift; sourceTree = ""; };
48 | 025683C7289AD7570029BC78 /* ScreenCaptureProtection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenCaptureProtection.swift; sourceTree = ""; };
49 | 02E953CE2868DD35002929FF /* VPNChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNChecker.swift; sourceTree = ""; };
50 | /* End PBXFileReference section */
51 |
52 | /* Begin PBXFrameworksBuildPhase section */
53 | 0203EAEF28661D9300A2E7A2 /* Frameworks */ = {
54 | isa = PBXFrameworksBuildPhase;
55 | buildActionMask = 2147483647;
56 | files = (
57 | );
58 | runOnlyForDeploymentPostprocessing = 0;
59 | };
60 | 0203EAF928661D9300A2E7A2 /* Frameworks */ = {
61 | isa = PBXFrameworksBuildPhase;
62 | buildActionMask = 2147483647;
63 | files = (
64 | 0203EAFD28661D9300A2E7A2 /* SecurityKit.framework in Frameworks */,
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | /* End PBXFrameworksBuildPhase section */
69 |
70 | /* Begin PBXGroup section */
71 | 0203EAE828661D9300A2E7A2 = {
72 | isa = PBXGroup;
73 | children = (
74 | 0203EAF428661D9300A2E7A2 /* SecurityKit */,
75 | 0203EB0028661D9300A2E7A2 /* SecurityKitTests */,
76 | 0203EAF328661D9300A2E7A2 /* Products */,
77 | );
78 | sourceTree = "";
79 | };
80 | 0203EAF328661D9300A2E7A2 /* Products */ = {
81 | isa = PBXGroup;
82 | children = (
83 | 0203EAF228661D9300A2E7A2 /* SecurityKit.framework */,
84 | 0203EAFC28661D9300A2E7A2 /* SecurityKitTests.xctest */,
85 | );
86 | name = Products;
87 | sourceTree = "";
88 | };
89 | 0203EAF428661D9300A2E7A2 /* SecurityKit */ = {
90 | isa = PBXGroup;
91 | children = (
92 | 0203EAF528661D9300A2E7A2 /* SecurityKit.h */,
93 | 0203EAF628661D9300A2E7A2 /* SecurityKit.docc */,
94 | 0203EB0C28661F8D00A2E7A2 /* JailBrokenDetection.swift */,
95 | 0247D8592868B07200D57EFE /* SimulatorDetection.swift */,
96 | 0247D85B2868BE4100D57EFE /* ReverseEngineering.swift */,
97 | 02E953CE2868DD35002929FF /* VPNChecker.swift */,
98 | 0219951C286A0F73001830A2 /* BackgroundLayer.swift */,
99 | 023E1CEF286ED94100061EB4 /* SecurityKit.swift */,
100 | 025683C7289AD7570029BC78 /* ScreenCaptureProtection.swift */,
101 | 02341F6E28C7AE94001E05C5 /* StringEncryption.swift */,
102 | 0234CA7E28CB84F800AC66A3 /* TestableStringEncryption.swift */,
103 | );
104 | path = SecurityKit;
105 | sourceTree = "";
106 | };
107 | 0203EB0028661D9300A2E7A2 /* SecurityKitTests */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 0234CA7928CB744800AC66A3 /* StringEncryptionTest.swift */,
111 | );
112 | path = SecurityKitTests;
113 | sourceTree = "";
114 | };
115 | /* End PBXGroup section */
116 |
117 | /* Begin PBXHeadersBuildPhase section */
118 | 0203EAED28661D9300A2E7A2 /* Headers */ = {
119 | isa = PBXHeadersBuildPhase;
120 | buildActionMask = 2147483647;
121 | files = (
122 | 0203EB0328661D9300A2E7A2 /* SecurityKit.h in Headers */,
123 | );
124 | runOnlyForDeploymentPostprocessing = 0;
125 | };
126 | /* End PBXHeadersBuildPhase section */
127 |
128 | /* Begin PBXNativeTarget section */
129 | 0203EAF128661D9300A2E7A2 /* SecurityKit */ = {
130 | isa = PBXNativeTarget;
131 | buildConfigurationList = 0203EB0628661D9300A2E7A2 /* Build configuration list for PBXNativeTarget "SecurityKit" */;
132 | buildPhases = (
133 | 0203EAED28661D9300A2E7A2 /* Headers */,
134 | 0203EAEE28661D9300A2E7A2 /* Sources */,
135 | 0203EAEF28661D9300A2E7A2 /* Frameworks */,
136 | 0203EAF028661D9300A2E7A2 /* Resources */,
137 | );
138 | buildRules = (
139 | );
140 | dependencies = (
141 | );
142 | name = SecurityKit;
143 | productName = SecurityKit;
144 | productReference = 0203EAF228661D9300A2E7A2 /* SecurityKit.framework */;
145 | productType = "com.apple.product-type.framework";
146 | };
147 | 0203EAFB28661D9300A2E7A2 /* SecurityKitTests */ = {
148 | isa = PBXNativeTarget;
149 | buildConfigurationList = 0203EB0928661D9300A2E7A2 /* Build configuration list for PBXNativeTarget "SecurityKitTests" */;
150 | buildPhases = (
151 | 0203EAF828661D9300A2E7A2 /* Sources */,
152 | 0203EAF928661D9300A2E7A2 /* Frameworks */,
153 | 0203EAFA28661D9300A2E7A2 /* Resources */,
154 | );
155 | buildRules = (
156 | );
157 | dependencies = (
158 | 0203EAFF28661D9300A2E7A2 /* PBXTargetDependency */,
159 | );
160 | name = SecurityKitTests;
161 | productName = SecurityKitTests;
162 | productReference = 0203EAFC28661D9300A2E7A2 /* SecurityKitTests.xctest */;
163 | productType = "com.apple.product-type.bundle.unit-test";
164 | };
165 | /* End PBXNativeTarget section */
166 |
167 | /* Begin PBXProject section */
168 | 0203EAE928661D9300A2E7A2 /* Project object */ = {
169 | isa = PBXProject;
170 | attributes = {
171 | BuildIndependentTargetsInParallel = 1;
172 | LastSwiftUpdateCheck = 1330;
173 | LastUpgradeCheck = 1330;
174 | TargetAttributes = {
175 | 0203EAF128661D9300A2E7A2 = {
176 | CreatedOnToolsVersion = 13.3;
177 | };
178 | 0203EAFB28661D9300A2E7A2 = {
179 | CreatedOnToolsVersion = 13.3;
180 | };
181 | };
182 | };
183 | buildConfigurationList = 0203EAEC28661D9300A2E7A2 /* Build configuration list for PBXProject "SecurityKit" */;
184 | compatibilityVersion = "Xcode 13.0";
185 | developmentRegion = en;
186 | hasScannedForEncodings = 0;
187 | knownRegions = (
188 | en,
189 | Base,
190 | );
191 | mainGroup = 0203EAE828661D9300A2E7A2;
192 | productRefGroup = 0203EAF328661D9300A2E7A2 /* Products */;
193 | projectDirPath = "";
194 | projectRoot = "";
195 | targets = (
196 | 0203EAF128661D9300A2E7A2 /* SecurityKit */,
197 | 0203EAFB28661D9300A2E7A2 /* SecurityKitTests */,
198 | );
199 | };
200 | /* End PBXProject section */
201 |
202 | /* Begin PBXResourcesBuildPhase section */
203 | 0203EAF028661D9300A2E7A2 /* Resources */ = {
204 | isa = PBXResourcesBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | );
208 | runOnlyForDeploymentPostprocessing = 0;
209 | };
210 | 0203EAFA28661D9300A2E7A2 /* Resources */ = {
211 | isa = PBXResourcesBuildPhase;
212 | buildActionMask = 2147483647;
213 | files = (
214 | );
215 | runOnlyForDeploymentPostprocessing = 0;
216 | };
217 | /* End PBXResourcesBuildPhase section */
218 |
219 | /* Begin PBXSourcesBuildPhase section */
220 | 0203EAEE28661D9300A2E7A2 /* Sources */ = {
221 | isa = PBXSourcesBuildPhase;
222 | buildActionMask = 2147483647;
223 | files = (
224 | 0247D85A2868B07200D57EFE /* SimulatorDetection.swift in Sources */,
225 | 0219951D286A0F73001830A2 /* BackgroundLayer.swift in Sources */,
226 | 02341F6F28C7AE94001E05C5 /* StringEncryption.swift in Sources */,
227 | 0203EAF728661D9300A2E7A2 /* SecurityKit.docc in Sources */,
228 | 025683C8289AD7570029BC78 /* ScreenCaptureProtection.swift in Sources */,
229 | 0234CA8128CB8CD500AC66A3 /* TestableStringEncryption.swift in Sources */,
230 | 02E953CF2868DD35002929FF /* VPNChecker.swift in Sources */,
231 | 023E1CF0286ED94100061EB4 /* SecurityKit.swift in Sources */,
232 | 0247D85C2868BE4100D57EFE /* ReverseEngineering.swift in Sources */,
233 | 0203EB0D28661F8D00A2E7A2 /* JailBrokenDetection.swift in Sources */,
234 | );
235 | runOnlyForDeploymentPostprocessing = 0;
236 | };
237 | 0203EAF828661D9300A2E7A2 /* Sources */ = {
238 | isa = PBXSourcesBuildPhase;
239 | buildActionMask = 2147483647;
240 | files = (
241 | 0234CA7A28CB744800AC66A3 /* StringEncryptionTest.swift in Sources */,
242 | );
243 | runOnlyForDeploymentPostprocessing = 0;
244 | };
245 | /* End PBXSourcesBuildPhase section */
246 |
247 | /* Begin PBXTargetDependency section */
248 | 0203EAFF28661D9300A2E7A2 /* PBXTargetDependency */ = {
249 | isa = PBXTargetDependency;
250 | target = 0203EAF128661D9300A2E7A2 /* SecurityKit */;
251 | targetProxy = 0203EAFE28661D9300A2E7A2 /* PBXContainerItemProxy */;
252 | };
253 | /* End PBXTargetDependency section */
254 |
255 | /* Begin XCBuildConfiguration section */
256 | 0203EB0428661D9300A2E7A2 /* Debug */ = {
257 | isa = XCBuildConfiguration;
258 | buildSettings = {
259 | ALWAYS_SEARCH_USER_PATHS = NO;
260 | CLANG_ANALYZER_NONNULL = YES;
261 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
262 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
263 | CLANG_ENABLE_MODULES = YES;
264 | CLANG_ENABLE_OBJC_ARC = YES;
265 | CLANG_ENABLE_OBJC_WEAK = YES;
266 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
267 | CLANG_WARN_BOOL_CONVERSION = YES;
268 | CLANG_WARN_COMMA = YES;
269 | CLANG_WARN_CONSTANT_CONVERSION = YES;
270 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
271 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
272 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
273 | CLANG_WARN_EMPTY_BODY = YES;
274 | CLANG_WARN_ENUM_CONVERSION = YES;
275 | CLANG_WARN_INFINITE_RECURSION = YES;
276 | CLANG_WARN_INT_CONVERSION = YES;
277 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
278 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
279 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
280 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
281 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
282 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
283 | CLANG_WARN_STRICT_PROTOTYPES = YES;
284 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
285 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
286 | CLANG_WARN_UNREACHABLE_CODE = YES;
287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
288 | COPY_PHASE_STRIP = NO;
289 | CURRENT_PROJECT_VERSION = 1;
290 | DEBUG_INFORMATION_FORMAT = dwarf;
291 | ENABLE_STRICT_OBJC_MSGSEND = YES;
292 | ENABLE_TESTABILITY = YES;
293 | GCC_C_LANGUAGE_STANDARD = gnu11;
294 | GCC_DYNAMIC_NO_PIC = NO;
295 | GCC_NO_COMMON_BLOCKS = YES;
296 | GCC_OPTIMIZATION_LEVEL = 0;
297 | GCC_PREPROCESSOR_DEFINITIONS = (
298 | "DEBUG=1",
299 | "$(inherited)",
300 | );
301 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
302 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
303 | GCC_WARN_UNDECLARED_SELECTOR = YES;
304 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
305 | GCC_WARN_UNUSED_FUNCTION = YES;
306 | GCC_WARN_UNUSED_VARIABLE = YES;
307 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
308 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
309 | MTL_FAST_MATH = YES;
310 | ONLY_ACTIVE_ARCH = YES;
311 | SDKROOT = iphoneos;
312 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
313 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
314 | SWIFT_VERSION = 5.0;
315 | VERSIONING_SYSTEM = "apple-generic";
316 | VERSION_INFO_PREFIX = "";
317 | };
318 | name = Debug;
319 | };
320 | 0203EB0528661D9300A2E7A2 /* Release */ = {
321 | isa = XCBuildConfiguration;
322 | buildSettings = {
323 | ALWAYS_SEARCH_USER_PATHS = NO;
324 | CLANG_ANALYZER_NONNULL = YES;
325 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
326 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
327 | CLANG_ENABLE_MODULES = YES;
328 | CLANG_ENABLE_OBJC_ARC = YES;
329 | CLANG_ENABLE_OBJC_WEAK = YES;
330 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
331 | CLANG_WARN_BOOL_CONVERSION = YES;
332 | CLANG_WARN_COMMA = YES;
333 | CLANG_WARN_CONSTANT_CONVERSION = YES;
334 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
335 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
336 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
337 | CLANG_WARN_EMPTY_BODY = YES;
338 | CLANG_WARN_ENUM_CONVERSION = YES;
339 | CLANG_WARN_INFINITE_RECURSION = YES;
340 | CLANG_WARN_INT_CONVERSION = YES;
341 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
342 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
343 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
344 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
345 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
346 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
347 | CLANG_WARN_STRICT_PROTOTYPES = YES;
348 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
349 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
350 | CLANG_WARN_UNREACHABLE_CODE = YES;
351 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
352 | COPY_PHASE_STRIP = NO;
353 | CURRENT_PROJECT_VERSION = 1;
354 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
355 | ENABLE_NS_ASSERTIONS = NO;
356 | ENABLE_STRICT_OBJC_MSGSEND = YES;
357 | GCC_C_LANGUAGE_STANDARD = gnu11;
358 | GCC_NO_COMMON_BLOCKS = YES;
359 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
360 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
361 | GCC_WARN_UNDECLARED_SELECTOR = YES;
362 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
363 | GCC_WARN_UNUSED_FUNCTION = YES;
364 | GCC_WARN_UNUSED_VARIABLE = YES;
365 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
366 | MTL_ENABLE_DEBUG_INFO = NO;
367 | MTL_FAST_MATH = YES;
368 | SDKROOT = iphoneos;
369 | SWIFT_COMPILATION_MODE = wholemodule;
370 | SWIFT_OPTIMIZATION_LEVEL = "-O";
371 | SWIFT_VERSION = 5.0;
372 | VALIDATE_PRODUCT = YES;
373 | VERSIONING_SYSTEM = "apple-generic";
374 | VERSION_INFO_PREFIX = "";
375 | };
376 | name = Release;
377 | };
378 | 0203EB0728661D9300A2E7A2 /* Debug */ = {
379 | isa = XCBuildConfiguration;
380 | buildSettings = {
381 | CODE_SIGN_STYLE = Automatic;
382 | CURRENT_PROJECT_VERSION = 1;
383 | DEFINES_MODULE = YES;
384 | DEVELOPMENT_TEAM = 3KZWVBAJSN;
385 | DYLIB_COMPATIBILITY_VERSION = 1;
386 | DYLIB_CURRENT_VERSION = 1;
387 | DYLIB_INSTALL_NAME_BASE = "@rpath";
388 | GENERATE_INFOPLIST_FILE = YES;
389 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
390 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
391 | LD_RUNPATH_SEARCH_PATHS = (
392 | "$(inherited)",
393 | "@executable_path/Frameworks",
394 | "@loader_path/Frameworks",
395 | );
396 | MARKETING_VERSION = 1.0;
397 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.SecurityKit;
398 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
399 | SKIP_INSTALL = YES;
400 | SWIFT_EMIT_LOC_STRINGS = YES;
401 | SWIFT_VERSION = 5.0;
402 | TARGETED_DEVICE_FAMILY = "1,2";
403 | };
404 | name = Debug;
405 | };
406 | 0203EB0828661D9300A2E7A2 /* Release */ = {
407 | isa = XCBuildConfiguration;
408 | buildSettings = {
409 | CODE_SIGN_STYLE = Automatic;
410 | CURRENT_PROJECT_VERSION = 1;
411 | DEFINES_MODULE = YES;
412 | DEVELOPMENT_TEAM = 3KZWVBAJSN;
413 | DYLIB_COMPATIBILITY_VERSION = 1;
414 | DYLIB_CURRENT_VERSION = 1;
415 | DYLIB_INSTALL_NAME_BASE = "@rpath";
416 | GENERATE_INFOPLIST_FILE = YES;
417 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
418 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
419 | LD_RUNPATH_SEARCH_PATHS = (
420 | "$(inherited)",
421 | "@executable_path/Frameworks",
422 | "@loader_path/Frameworks",
423 | );
424 | MARKETING_VERSION = 1.0;
425 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.SecurityKit;
426 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
427 | SKIP_INSTALL = YES;
428 | SWIFT_EMIT_LOC_STRINGS = YES;
429 | SWIFT_VERSION = 5.0;
430 | TARGETED_DEVICE_FAMILY = "1,2";
431 | };
432 | name = Release;
433 | };
434 | 0203EB0A28661D9300A2E7A2 /* Debug */ = {
435 | isa = XCBuildConfiguration;
436 | buildSettings = {
437 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
438 | CODE_SIGN_STYLE = Automatic;
439 | CURRENT_PROJECT_VERSION = 1;
440 | DEVELOPMENT_TEAM = 3KZWVBAJSN;
441 | GENERATE_INFOPLIST_FILE = YES;
442 | MARKETING_VERSION = 1.0;
443 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.SecurityKitTests;
444 | PRODUCT_NAME = "$(TARGET_NAME)";
445 | SWIFT_EMIT_LOC_STRINGS = NO;
446 | SWIFT_VERSION = 5.0;
447 | TARGETED_DEVICE_FAMILY = "1,2";
448 | };
449 | name = Debug;
450 | };
451 | 0203EB0B28661D9300A2E7A2 /* Release */ = {
452 | isa = XCBuildConfiguration;
453 | buildSettings = {
454 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
455 | CODE_SIGN_STYLE = Automatic;
456 | CURRENT_PROJECT_VERSION = 1;
457 | DEVELOPMENT_TEAM = 3KZWVBAJSN;
458 | GENERATE_INFOPLIST_FILE = YES;
459 | MARKETING_VERSION = 1.0;
460 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.SecurityKitTests;
461 | PRODUCT_NAME = "$(TARGET_NAME)";
462 | SWIFT_EMIT_LOC_STRINGS = NO;
463 | SWIFT_VERSION = 5.0;
464 | TARGETED_DEVICE_FAMILY = "1,2";
465 | };
466 | name = Release;
467 | };
468 | /* End XCBuildConfiguration section */
469 |
470 | /* Begin XCConfigurationList section */
471 | 0203EAEC28661D9300A2E7A2 /* Build configuration list for PBXProject "SecurityKit" */ = {
472 | isa = XCConfigurationList;
473 | buildConfigurations = (
474 | 0203EB0428661D9300A2E7A2 /* Debug */,
475 | 0203EB0528661D9300A2E7A2 /* Release */,
476 | );
477 | defaultConfigurationIsVisible = 0;
478 | defaultConfigurationName = Release;
479 | };
480 | 0203EB0628661D9300A2E7A2 /* Build configuration list for PBXNativeTarget "SecurityKit" */ = {
481 | isa = XCConfigurationList;
482 | buildConfigurations = (
483 | 0203EB0728661D9300A2E7A2 /* Debug */,
484 | 0203EB0828661D9300A2E7A2 /* Release */,
485 | );
486 | defaultConfigurationIsVisible = 0;
487 | defaultConfigurationName = Release;
488 | };
489 | 0203EB0928661D9300A2E7A2 /* Build configuration list for PBXNativeTarget "SecurityKitTests" */ = {
490 | isa = XCConfigurationList;
491 | buildConfigurations = (
492 | 0203EB0A28661D9300A2E7A2 /* Debug */,
493 | 0203EB0B28661D9300A2E7A2 /* Release */,
494 | );
495 | defaultConfigurationIsVisible = 0;
496 | defaultConfigurationName = Release;
497 | };
498 | /* End XCConfigurationList section */
499 | };
500 | rootObject = 0203EAE928661D9300A2E7A2 /* Project object */;
501 | }
502 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit.xcodeproj/project.xcworkspace/xcuserdata/mehran.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mehrankmlf/SecurityKit/8c2a2ae2b4f057c3007b667bf9dea65bc3f967ce/SecurityKit/SecurityKit.xcodeproj/project.xcworkspace/xcuserdata/mehran.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit.xcodeproj/xcuserdata/mehran.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SecurityKit.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/BackgroundLayer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BackgroundLayer.swift
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 4/6/1401 AP.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | internal class SecureLayer {
12 |
13 | static func showImage(window : UIWindow?, with image : UIImage?) {
14 | guard let window = window,let image = image else{return}
15 | let imageView = UIImageView(image: image)
16 | imageView.backgroundColor = UIColor.white
17 | imageView.isUserInteractionEnabled = false
18 | imageView.contentMode = .scaleAspectFit
19 | imageView.snapshotView(afterScreenUpdates: true)
20 | imageView.frame = window.bounds
21 | window.addSubview(imageView)
22 | }
23 |
24 | static func removeOverlayImage(_ window:inout UIWindow?){
25 | guard let window = window else{return}
26 | for view in window.subviews{
27 | if view is UIImageView{
28 | view.removeFromSuperview()
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/JailBrokenDetection.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JailBrokenDetection.swift
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 4/3/1401 AP.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | internal class JailBreakDetection {
12 |
13 | internal static func isJailBroken() -> Bool {
14 | let isCydiaInstalled = hasCydiaInstalled()
15 | let fileCheck = isPathsExist()
16 | let directories = isDirectoriesWriteable()
17 | let suspiciousApps = isContainsSuspiciousApps()
18 |
19 | return isCydiaInstalled ||
20 | fileCheck ||
21 | directories ||
22 | suspiciousApps ? true : false
23 | }
24 |
25 | //check if cydia is installed (using URI Scheme)
26 | static func hasCydiaInstalled() -> Bool {
27 | return UIApplication.shared.canOpenURL(URL(string: "cydia://")!)
28 | }
29 |
30 | //suspicious system and app paths to check
31 | private static var suspicousAppandSystemPaths: [String] {
32 | return [
33 | "/usr/sbin/frida-server",
34 | "/etc/apt/sources.list.d/electra.list",
35 | "/etc/apt/sources.list.d/sileo.sources",
36 | "/.bootstrapped_electra",
37 | "/usr/lib/libjailbreak.dylib",
38 | "/jb/lzma",
39 | "/.cydia_no_stash",
40 | "/.installed_unc0ver",
41 | "/jb/offsets.plist",
42 | "/usr/share/jailbreak/injectme.plist",
43 | "/etc/apt/undecimus/undecimus.list",
44 | "/var/lib/dpkg/info/mobilesubstrate.md5sums",
45 | "/Library/MobileSubstrate/MobileSubstrate.dylib",
46 | "/jb/jailbreakd.plist",
47 | "/jb/amfid_payload.dylib",
48 | "/jb/libjailbreak.dylib",
49 | "/usr/libexec/cydia/firmware.sh",
50 | "/var/lib/cydia",
51 | "/etc/apt",
52 | "/private/var/lib/apt",
53 | "/private/var/Users/",
54 | "/var/log/apt",
55 | "/Applications/Cydia.app",
56 | "/private/var/stash",
57 | "/private/var/lib/apt/",
58 | "/private/var/lib/cydia",
59 | "/private/var/cache/apt/",
60 | "/private/var/log/syslog",
61 | "/private/var/tmp/cydia.log",
62 | "/Applications/Icy.app",
63 | "/Applications/MxTube.app",
64 | "/Applications/RockApp.app",
65 | "/Applications/blackra1n.app",
66 | "/Applications/SBSettings.app",
67 | "/Applications/FakeCarrier.app",
68 | "/Applications/WinterBoard.app",
69 | "/Applications/IntelliScreen.app",
70 | "/private/var/mobile/Library/SBSettings/Themes",
71 | "/Library/MobileSubstrate/CydiaSubstrate.dylib",
72 | "/System/Library/LaunchDaemons/com.ikey.bbot.plist",
73 | "/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
74 | "/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
75 | "/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist"
76 | ]
77 | }
78 |
79 | private static func isPathsExist() -> Bool {
80 | for path in suspicousAppandSystemPaths {
81 | if FileManager.default.fileExists(atPath: path){
82 | return true
83 | }
84 | }
85 | return false
86 | }
87 |
88 | private static var directories: [String] {
89 | return [
90 | "/",
91 | "/root/",
92 | "/private/",
93 | "/jb/"
94 | ]
95 | }
96 |
97 | private static func isDirectoriesWriteable() -> Bool {
98 | // Checks if the restricted directories are writeable.
99 | for path in directories {
100 | do{
101 | let filePath = path + UUID().uuidString
102 | try "i escaped the Jail".write(toFile: filePath, atomically: true, encoding: .utf8)
103 | try FileManager.default.removeItem(atPath: filePath)
104 | return true
105 | }catch let error{print(error.localizedDescription)}
106 | }
107 | return false
108 | }
109 |
110 | //suspicious apps path to check
111 | private static var suspiciousAppsPathToCheck: [String] {
112 | return ["/Applications/Cydia.app",
113 | "/Applications/blackra1n.app",
114 | "/Applications/FakeCarrier.app",
115 | "/Applications/Icy.app",
116 | "/Applications/IntelliScreen.app",
117 | "/Applications/MxTube.app",
118 | "/Applications/RockApp.app",
119 | "/Applications/SBSettings.app",
120 | "/Applications/WinterBoard.app"
121 | ]
122 | }
123 |
124 | //Check if suspicious apps (Cydia, FakeCarrier, Icy etc.) is installed
125 | private static func isContainsSuspiciousApps() -> Bool {
126 | for path in suspiciousAppsPathToCheck {
127 | if FileManager.default.fileExists(atPath: path) {
128 | return true
129 | }
130 | }
131 | return false
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/ReverseEngineering.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReverseEngineering.swift
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 4/5/1401 AP.
6 | //
7 |
8 | import Foundation
9 | import MachO.dyld
10 |
11 | internal class ReverseEngineering {
12 |
13 | // Detect reverse engineering tools
14 | internal static func isReverseEngineeringTools() -> Bool {
15 | let dyld = checkDYLD()
16 | let frida = isFridaRunning()
17 | return dyld || frida ? true : false
18 | }
19 |
20 | private static func checkDYLD() -> Bool {
21 | let suspiciousLibraries = [
22 | "FridaGadget",
23 | "frida",
24 | "cynject",
25 | "libcycript"
26 | ]
27 | for libraryIndex in 0..<_dyld_image_count() {
28 |
29 | guard let loadedLibrary = String(validatingUTF8: _dyld_get_image_name(libraryIndex)) else { continue }
30 | for suspiciousLibrary in suspiciousLibraries {
31 | if loadedLibrary.lowercased().contains(suspiciousLibrary.lowercased()) {
32 | return true
33 | }
34 | }
35 | }
36 | return false
37 | }
38 |
39 | private static func isFridaRunning() -> Bool {
40 | func swapBytesIfNeeded(port: in_port_t) -> in_port_t {
41 | let littleEndian = Int(OSHostByteOrder()) == OSLittleEndian
42 | return littleEndian ? _OSSwapInt16(port) : port
43 | }
44 |
45 | var serverAddress = sockaddr_in()
46 | serverAddress.sin_family = sa_family_t(AF_INET)
47 | serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1")
48 | serverAddress.sin_port = swapBytesIfNeeded(port: in_port_t(27042))
49 | let sock = socket(AF_INET, SOCK_STREAM, 0)
50 |
51 | let result = withUnsafePointer(to: &serverAddress) {
52 | $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
53 | connect(sock, $0, socklen_t(MemoryLayout.stride))
54 | }
55 | }
56 | if result != -1 {
57 | return true
58 | }
59 | return false
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/ScreenCaptureProtection.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScreenCaptureProtection.swift
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 5/12/1401 AP.
6 | //
7 |
8 | import Foundation
9 |
10 | import UIKit
11 |
12 | private extension UIView {
13 |
14 | enum Constant {
15 | case textFieldTag
16 | var num : Int {
17 | switch self {
18 | case .textFieldTag:
19 | return Int.max
20 | }
21 | }
22 | }
23 |
24 | // Create a layer on screen to hide sensitive data
25 | func makeSecureTextField() {
26 |
27 | guard superview != nil else {
28 | for subview in subviews { //to avoid layer cyclic crash, when it is a topmost view, adding all its subviews in textfield's layer, TODO: Find a better logic.
29 | subview.makeSecureTextField()
30 | }
31 | return
32 | }
33 |
34 | DispatchQueue.main.async {
35 | let field = UITextField()
36 | field.isSecureTextEntry = true
37 | field.tag = Constant.textFieldTag.num
38 | self.addSubview(field)
39 | field.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
40 | field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
41 | self.layer.superlayer?.addSublayer(field.layer)
42 | field.layer.sublayers?.first?.addSublayer(self.layer)
43 | }
44 | }
45 |
46 | // Remove added layer to the screen
47 | func removeSecureTextField() {
48 | if let guardView = subviews.first(where: { $0.tag == Constant.textFieldTag.num }) {
49 | guardView.removeFromSuperview()
50 | }
51 | }
52 | }
53 |
54 | public class ScreenCaptureProtection {
55 |
56 | public static let shared = ScreenCaptureProtection()
57 |
58 | private init() {}
59 |
60 | public func makeProtection(`for` view: UIView) {
61 | view.makeSecureTextField()
62 | }
63 |
64 | public func removeScreenProtection(`for` view: UIView) {
65 | view.removeSecureTextField()
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/SecurityKit.docc/SecurityKit.md:
--------------------------------------------------------------------------------
1 | # ``SecurityKit``
2 |
3 | Summary
4 |
5 | ## Overview
6 |
7 | Text
8 |
9 | ## Topics
10 |
11 | ### Group
12 |
13 | - ``Symbol``
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/SecurityKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // SecurityKit.h
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 4/3/1401 AP.
6 | //
7 |
8 | #import
9 |
10 | //! Project version number for SecurityKit.
11 | FOUNDATION_EXPORT double SecurityKitVersionNumber;
12 |
13 | //! Project version string for SecurityKit.
14 | FOUNDATION_EXPORT const unsigned char SecurityKitVersionString[];
15 |
16 | // In this header, you should import all the public headers of your framework using statements like #import
17 |
18 |
19 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/SecurityKit.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SecurityKit.swift
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 4/10/1401 AP.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | public class SecurityKit {
12 |
13 | /**
14 | Detect when device is JAILBROKEN
15 |
16 | - returns: Bool
17 | - warning: none
18 |
19 | # Example #
20 | ```
21 | let jailBroken = SecurityKit.isDeviceJailBroken()
22 | ```
23 | */
24 | public static func isDeviceJailBroken() -> Bool {
25 | return JailBreakDetection.isJailBroken()
26 | }
27 |
28 |
29 | /**
30 | Detect when device is SIMULATOR
31 |
32 | - returns: Bool
33 | - warning: none
34 |
35 | # Example #
36 | ```
37 | //
38 | let deviceSimulator = SecurityKit.isDeviceSimulator()
39 | ```
40 | */
41 | public static func isDeviceSimulator() -> Bool {
42 | return Platform.isSimulator()
43 | }
44 |
45 |
46 | /**
47 | Detect when REVERSE ENGINEERING tools have executed like : Frida, Cynject
48 |
49 | - returns: Bool
50 | - warning: none
51 |
52 | # Example #
53 | ```
54 | //
55 | let reverseEngineering = SecurityKit.isReverseEngineeringToolsExecuted()
56 | ```
57 | */
58 | public static func isReverseEngineeringToolsExecuted() -> Bool {
59 | return ReverseEngineering.isReverseEngineeringTools()
60 | }
61 |
62 |
63 | /**
64 | Detect when VPN is Connected in device
65 |
66 | - returns: Bool
67 | - warning: none
68 |
69 | # Example #
70 | ```
71 | //
72 | let vpnConnected = SecurityKit.isVPNConnected()
73 | ```
74 | */
75 | public static func isVPNConnected() -> Bool {
76 | return VPNChecker.isVPNConnected()
77 | }
78 |
79 |
80 | /**
81 | Before your app enters the background you can go and adjust the this UI to simply not show the user’s sensitive data
82 | by addSubview UIImage layer
83 |
84 | - parameter UIWindow?
85 | - parameter UIImage?
86 | - warning: none
87 |
88 | # Notes: #
89 | Use this methods for detect when app goes to background
90 | 1. applicationWillResignActive(_:) method in the AppDelegate
91 | 2. sceneWillResignActive(_ scene:) method in SceneDelegate
92 |
93 | # Example #
94 | ```
95 | //
96 | SecurityKit.createSecureScreenShot(window : window, image : image)
97 | ```
98 | */
99 | public static func createSecureScreenShot(window : UIWindow?, image : UIImage) {
100 | SecureLayer.showImage(window: window, with: image)
101 | }
102 |
103 |
104 | /**
105 | Before your app become active you can remove added overlay from UIWindow
106 |
107 | - parameter UIWindow
108 | - warning: none
109 |
110 | # Notes: #
111 | Use this methods for detect when app goes to foreground
112 | 1. applicationWillEnterForeground(_:) method in the AppDelegate
113 | 2. sceneDidBecomeActive(_ scene:) method in SceneDelegate
114 |
115 | # Example #
116 | ```
117 | //
118 | SecurityKit.removeSecureScreenShot(window:inout window)
119 | ```
120 | */
121 | public static func removeSecureScreenShot(window:inout UIWindow?) {
122 | SecureLayer.removeOverlayImage(&window)
123 | }
124 |
125 | /**
126 | Hide Sensitive String data from run time binary
127 |
128 | - parameter String
129 | - parameter String
130 | - returns [UInt8]
131 | - warning: none
132 |
133 | # Notes: #
134 | Use this method use for encrypt string
135 | base on XOR alghorithm
136 | # Example #
137 | ```
138 | //
139 | SecurityKit.stringEncryption(plainText : "String", encryptionKey: "String")
140 | ```
141 | */
142 | public static func stringEncryption(plainText : String, encryptionKey: String) -> [UInt8] {
143 | return XOREncryption.encryption(plainText: plainText, encryptionKey: encryptionKey)
144 | }
145 |
146 | /**
147 | Hide Sensitive String data from run time binary
148 |
149 | - parameter String
150 | - parameter String
151 | - returns String
152 | - warning: none
153 |
154 | # Notes: #
155 | Use this method use for array of [UInt8]
156 | # Example #
157 | ```
158 | //
159 | SecurityKit.stringDecryption(cypherText: [UInt8]?, decryptionKey : "String")
160 | ```
161 | */
162 | public static func stringDecryption(cypherText: [UInt8]?, decryptionKey : String?) -> String {
163 | return XOREncryption.decryption(cypherText: cypherText, decryptionKey: decryptionKey)
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/SimulatorDetection.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SimulatorDetection.swift
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 4/5/1401 AP.
6 | //
7 |
8 | import Foundation
9 |
10 | internal class Platform {
11 |
12 | internal static func isSimulator() -> Bool {
13 | return runTime() || compileTime()
14 | }
15 |
16 | private static func runTime() -> Bool {
17 | return ProcessInfo().environment["SIMULATOR_DEVICE_NAME"] != nil
18 | }
19 |
20 | private static func compileTime() -> Bool {
21 | #if targetEnvironment(simulator)
22 | // We're on the simulator
23 | return true
24 | #else
25 | // We're on a device
26 | return false
27 | #endif
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/StringEncryption.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StringEncryption.swift
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 6/15/1401 AP.
6 | //
7 |
8 | import Foundation
9 |
10 | internal class XOREncryption {
11 |
12 | static func encryption(plainText: String?, encryptionKey : String?) -> [UInt8] {
13 |
14 | guard let plainText = plainText,
15 | let encryptionKey = encryptionKey
16 | else { return [UInt8]() }
17 |
18 | var encrypted = [UInt8]()
19 | let text = [UInt8](plainText.utf8)
20 | let key = [UInt8](encryptionKey.utf8)
21 | let length = key.count
22 |
23 | // encrypt bytes base on XOR data encryption
24 | for t in text.enumerated() {
25 | encrypted.append(t.element ^ key[t.offset % length])
26 | }
27 | return encrypted
28 | }
29 |
30 | static func decryption(cypherText: [UInt8]?, decryptionKey : String?) -> String {
31 |
32 | guard let cypherText = cypherText,
33 | let decryptionKey = decryptionKey
34 | else { return "" }
35 |
36 | var decrypted = [UInt8]()
37 | let cypher = cypherText
38 | let key = [UInt8](decryptionKey.utf8)
39 | let length = key.count
40 |
41 | /// decrypt bytes base on XOR data encryption
42 | for c in cypher.enumerated() {
43 | decrypted.append(c.element ^ key[c.offset % length])
44 | }
45 | return String(bytes: decrypted, encoding: .utf8)!
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/TestableStringEncryption.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestableStringEncryption.swift
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 6/18/1401 AP.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol XOREncryptionProtocol {
11 | func encryption(plainText: String?, encryptionKey : String?) -> [UInt8]
12 | func decryption(cypherText: [UInt8]?, decryptionKey : String?) -> String
13 | }
14 | // this class helps to write unit test for encryption process
15 | internal class TestableStringEncryption: XOREncryptionProtocol {
16 | func encryption(plainText: String?, encryptionKey: String?) -> [UInt8] {
17 | XOREncryption.encryption(plainText: plainText, encryptionKey: encryptionKey)
18 | }
19 |
20 | func decryption(cypherText: [UInt8]?, decryptionKey: String?) -> String {
21 | return XOREncryption.decryption(cypherText: cypherText, decryptionKey: decryptionKey)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKit/VPNChecker.swift:
--------------------------------------------------------------------------------
1 | //
2 | // VPNChecker.swift
3 | // SecurityKit
4 | //
5 | // Created by Mehran on 4/5/1401 AP.
6 | //
7 |
8 | import Foundation
9 |
10 | internal class VPNChecker {
11 |
12 | internal static func isVPNConnected() -> Bool {
13 | return vpnStatus()
14 | }
15 | // Check vpn status
16 | private static func vpnStatus() -> Bool {
17 | let cfDict = CFNetworkCopySystemProxySettings()
18 | let nsDict = cfDict!.takeRetainedValue() as NSDictionary
19 | let keys = nsDict["__SCOPED__"] as! NSDictionary
20 |
21 | for key: String in keys.allKeys as! [String] {
22 | if (key == "tap" ||
23 | key == "tun" ||
24 | key == "ppp" ||
25 | key == "ipsec" ||
26 | key == "ipsec0" ||
27 | key == "utun1" ||
28 | key == "utun2") {
29 | return true
30 | }
31 | }
32 | return false
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/SecurityKit/SecurityKitTests/StringEncryptionTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StringEncryptionTest.swift
3 | // SecurityKitTests
4 | //
5 | // Created by Mehran on 6/18/1401 AP.
6 | //
7 |
8 | import XCTest
9 | @testable import SecurityKit
10 |
11 | class StringEncryptionTest: XCTestCase {
12 |
13 | var sut : XOREncryptionProtocol!
14 |
15 | override func setUp() {
16 | sut = TestableStringEncryption()
17 | }
18 |
19 | override func tearDown() {
20 | sut = nil
21 | super.tearDown()
22 | }
23 |
24 | func testBytesByXOREncryption_WhenCelled_ShouldReturnValidByteArray() {
25 | let plain = "PlainText"
26 | let key = "key"
27 | let result = sut.encryption(plainText: plain, encryptionKey: key)
28 | XCTAssertTrue(result as Any is [UInt8])
29 | XCTAssertEqual(result.count, "PlainText".count)
30 | }
31 |
32 | func testBytesByXORDecryption_WhenCelled_ShouldReturnValidString() {
33 | let cypher : [UInt8] = [59, 9, 24, 2, 11, 45, 14, 29, 13]
34 | let key = "key"
35 | let result = sut.decryption(cypherText: cypher, decryptionKey: key)
36 | XCTAssertTrue(result as Any is String)
37 | XCTAssertEqual(result, "PlainText")
38 | }
39 | }
40 |
--------------------------------------------------------------------------------