- 인쇄
- PDF
iOS SDK
- 인쇄
- PDF
Classic/VPC 환경에서 이용 가능합니다.
iOS 앱의 보안을 위한 App Safer iOS SDK 사용 방법에 대해 설명합니다. SDK를 설치하고 환경을 구성함으로써 App Safer를 연동할 수 있습니다.
App Safer를 적용하는 전반적인 샘플 코드는 샘플 코드에서 확인해 주십시오.
SDK 설치 및 환경 구성
App Safer에서 제공하는 기능을 이용하려면 먼저 iOS SDK를 설치한 후 환경을 구성해 주십시오. iOS 앱용 App Safer의 라이브러리는 하나의 프레임워크로 구성되어 있으며, Bitcode Enable/Disable 환경을 모두 지원합니다. 구성하는 방법은 다음과 같습니다.
Xcode 8.0 이상의 환경에서 빌드하는 것을 권장합니다.
- 다운로드한 SDK를 임의의 디렉터리에서 압축 해제해 주십시오.
- 프로젝트의 Bitcode 설정을 확인해 주십시오.
- 경로: Build Settings > Build Options > Enable Bitcode
- App Safer 프레임워크를 프로젝트에 추가해 주십시오.
- 경로: File > Add Files to "Your Project"... > Options > Copy items if needed 선택 > AppSaferFramework.framework 선택 > Add 클릭
- Swift를 사용하는 경우 Objective-C와의 호환을 위해 Bridging Header를 생성해 주십시오.
- 헤더 파일 생성: File > New File... > Header File 선택 > 프로젝트 루트 위치에 파일명 'AppSaferFramework-Bridging-Header.h'으로 설정
- 헤더 파일을 빌드 설정에 추가: Build Settings > Swift Compiler - General > Objective-C Bridging Header > AppSaferFramework-Bridging-Header.h에서 다음 코드 입력
#ifndef AppSaferFramework_Bridging_Header_h #define AppSaferFramework_Bridging_Header_h #import <AppSaferFramework/AppSaferFramework.h> #endif /* AppSaferFramework_Bridging_Header_h */
디버깅 방지 기능 적용
디버깅 방지 기능은 SDK를 설치하면 자동으로 적용됩니다. 만약 디버깅이 필요한 경우 App Safer SDK를 일시적으로 적용 해제한 상태에서 사용해 주십시오.
캡처 차단 및 탐지 기능 적용
App Safer SDK에서 제공하는 앱 미리 보기 화면 보호, 스크린샷 탐지, 녹화 및 미러링 시 화면 보호 기능을 적용하려면 API를 호출해야 합니다.
- iOS 13.0 미만: AppDelegate에서 앱 생명 주기에 맞춰 App Safer API 호출
- iOS 13.0 이상: SceneDelegate에서 앱 생명 주기에 맞춰 App Safer API 호출
API를 호출하는 예제는 다음과 같습니다.
selector
를 등록하면 캡처 이벤트 탐지 시 callback을 받고 원하는 동작을 수행할 수 있습니다.
AppDelegate (Swift)
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
@objc func didDetectCapture() -> Void {
print("[DETECT] Detected Screenshot in AppDelegate");
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
AppSafer.registerScreenProtectionObserver(window, observer: self, selector: #selector(didDetectCapture))
return true
}
func applicationWillResignActive(_ application: UIApplication) {
AppSafer.preventScreenshot(window, isInvisible: 0)
}
func applicationDidEnterBackground(_ application: UIApplication) {
AppSafer.preventScreenshot(window, isInvisible: 1)
}
func applicationWillEnterForeground(_ application: UIApplication) {
AppSafer.preventScreenshot(window, isInvisible: 0)
}
func applicationDidBecomeActive(_ application: UIApplication) {
AppSafer.preventScreenshot(window, isInvisible: 1)
}
}
AppDelegate (Objective-C)
#import "AppDelegate.h"
#import <AppSaferFramework/AppSaferFramework.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (void)didDetectCapture {
NSLog(@"[DETECT] Detected Screenshot in AppDelegate");
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions {
[AppSafer registerScreenProtectionObserver:_window observer:self selector:@selector(didDetectCapture)];
return YES;
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[AppSafer preventScreenshot:_window isInvisible:false];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[AppSafer preventScreenshot:_window isInvisible:false];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[AppSafer preventScreenshot:_window isInvisible:true];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[AppSafer preventScreenshot:_window isInvisible:true];
}
@end
SceneDelegate (Swift)
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
@objc func didDetectCapture() -> Void {
print("[DETECT] Detected Screenshot in AppDelegate");
}
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = ContentView()
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
AppSafer.registerScreenProtectionObserver(window, observer: self, selector: #selector(didDetectCapture))
}
}
func sceneDidBecomeActive(_ scene: UIScene) {
AppSafer.preventScreenshot(window, isInvisible: 0)
}
func sceneWillResignActive(_ scene: UIScene) {
AppSafer.preventScreenshot(window, isInvisible: 1)
}
func sceneWillEnterForeground(_ scene: UIScene) {
AppSafer.preventScreenshot(window, isInvisible: 0)
}
func sceneDidEnterBackground(_ scene: UIScene) {
AppSafer.preventScreenshot(window, isInvisible: 1)
}
}
SceneDelegate (Objective-C)
#import "SceneDelegate.h"
#import <AppSaferFramework/AppSaferFramework.h>
@interface SceneDelegate ()
@end
@implementation SceneDelegate
- (void)didDetectCapture {
NSLog(@"[DETECT] Detected Screenshot in SceneDelegate");
}
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0)) {
[AppSafer registerScreenProtectionObserver:_window observer:self selector:@selector(didDetectCapture)];
}
- (void)sceneWillEnterForeground:(UIScene *)scene API_AVAILABLE(ios(13.0)) {
[AppSafer preventScreenshot:_window isInvisible:false];
}
- (void)sceneDidBecomeActive:(UIScene *)scene API_AVAILABLE(ios(13.0)) {
[AppSafer preventScreenshot:_window isInvisible:false];
}
- (void)sceneWillResignActive:(UIScene *)scene API_AVAILABLE(ios(13.0)) {
[AppSafer preventScreenshot:_window isInvisible:true];
}
- (void)sceneDidEnterBackground:(UIScene *)scene API_AVAILABLE(ios(13.0)) {
[AppSafer preventScreenshot:_window isInvisible:true];
}
@end
제공 API
App Safer API는 2개의 패키지를 통해 제공되며, 각 패키지에서 호출 가능한 API는 다음과 같습니다.
- AppSafer
이름 | 설명 |
---|---|
initAppSafer | AppSafer을 사용하기 위해 초기화 |
checkTampering | 실시간 보안 탐지
|
setUserId | 사용자 식별자 설정 |
- AppSaferDelegate
- 비동기로 동작하는 Callback 함수입니다.
- 결과 처리는 AppSaferDelegate를 통해 위임됩니다.
- 검사 결과를 받으려면 AppSaferDelegate를 구현한 후 initAppSafer 함수를 이용해 등록해야 합니다.
- Swift를 사용할 경우
struct
가 아닌class
에 구현해야 하며 AppSaferDelegate와 NSObject를 모두 추가해야 합니다.
이름 | 필수 여부 | 설명 |
---|---|---|
appSaferDidInitFinish | 필수 | App Safer의 초기화 결과 확인 |
appSaferDidCheckTamperingFinish | 필수 | checkTampering 함수 수행 결과 확인 |
appSaferDetectedJailbreak | 선택 | 기기의 탈옥 행위 탐지 시 호출 |
appSaferDetectedSimulator | 선택 | 기기가 가상 머신에서 실행 중임을 탐지 시 호출 |
appSaferDetectedDebugging | 선택 | 디버깅 행위 탐지 시 호출 |
appSaferDetectedMemoryTampered | 선택 | 앱의 메모리 변조 탐지 시 호출 |
initAppSafer
App Safer는 초기화를 성공해야만 사용할 수 있습니다. App Safer를 초기화하려면 아래 코드를 사용해 주십시오.
로그를 전송하는 데 필요한 정보 및 전역으로 사용되는 변수가 초기화됩니다.
- 초기화 성공 여부를 전달받으려면 AppSaferDelegate를 구현해야 합니다.
func initAppSafer(_ delegate: AppSaferDelegate!, serviceCode: String!, key appsaferKey: String!) -> Int32
- (int) initAppSafer:(id<AppSaferDelegate>)delegate serviceCode:(NSString *)serviceCode key:(NSString *)appsaferKey
매개변수
매개변수 설명 delegate AppSaferDelegate가 구현된 인스턴스 serviceCode App Safer를 이용하기 위한 코드
네이버 클라우드 플랫폼 사용자는 반드시 'ncloud'를 전달appsaferKey 콘솔에서 앱 등록 시 생성된 App Safer Key 값 반환 값
반환 값 설명 SUCCESS(0) 성공 FAIL(-1) 실패 예제
struct ContentView: View { func initAppSaferExample() { // APP_SAFER_KEY generated when registering an app to the Console let result = AppSafer().initAppSafer(AppSaferDelegator.delegator, serviceCode: "ncloud", key: "<APP_SAFER_KEY>") NSLog("initAppSafer() result: %d", result); if(result == SUCCESS) { // init success } else if(result == FAIL) { // init fail } } var body: some View { Button("initAppSafer") { initAppSaferExample() } } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (IBAction)initAppSaferExample:(id)sender { AppSafer *appSafer = [[AppSafer alloc] init]; int res = FAIL; if(appSafer != nil) { // APP_SAFER_KEY generated when registering an app to the Console res = [appSafer initAppSafer:self serviceCode:@"ncloud" key:@"<APP_SAFER_KEY>"]; NSLog(@"initAppSafer() result: %d", res); if(res == SUCCESS) { // init success } } }
checkTampering
실시간 보안 탐지 기능을 실행하려면 아래 코드를 사용해 주십시오.
func checkTampering()
- (int)checkTampering
반환 값
반환 값 설명 SUCCESS(0) 검사 시작 성공 FAIL(-1) 검사 시작 실패 BLOCK(2) 보안 정책을 위반하여 차단 BEFOREINIT(3) App Safer가 초기화되지 않음 예제
struct ContentView: View { func checkTamperingExample() { let result = AppSafer().checkTampering() switch(result) { case FAIL: print("Failed to check tampering") break case SUCCESS: print("Check Tampering Success") break case BLOCK: print("Device is blocked") break case BEFOREINIT: print("AppSafer is not initialized") break default: break } } var body: some View { Button("checkTampering") { checkTamperingExample() } } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (IBAction)checkAppSafer:(id)sender { AppSafer *appSafer = [[AppSafer alloc] init]; if(appSafer != nil) { int res = [appSafer checkTampering]; switch(res) { case FAIL: NSLog(@"Failed to check tampering"); break; case SUCCESS: NSLog(@"Check Tampering Success"); break; case BLOCK: NSLog(@"Device is blocked"); break; case BEFOREINIT: NSLog(@"AppSafer is not initialized"); break; } } else { NSLog(@"AppSafer is nil"); } } @end
setUserId
초기화 및 탐지 이벤트 발생 시 App Safer 서버로 전송되는 로그에 사용자 식별자를 포함하려면 아래 코드를 사용해 주십시오.
func setUserId(_ userId: String!) -> Int32
- (int)setUserId:(NSString *)userId
매개변수
매개변수 설명 userId 사용자 식별자 반환 값
반환 값 설명 SUCCESS(0) 설정 성공 FAIL(-1) 설정 실패 예제
struct ContentView: View { func setUserIdExample(_ userId: String) { print("setUserId(\(userId))") let result = AppSafer().setUserId(userId) switch(result) { case FAIL: print("Failed to set userId: \(userId)") break case SUCCESS: print("setUserId() Success: \(userId)") break default: break } } var body: some View { Button("setUserId") { setUserIdExample("ExampleUserId") } } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (IBAction)setUserId:(id)sender { AppSafer *appSafer = [[AppSafer alloc] init]; if(appSafer != nil) { NSLog(@"setUserId(%@)", [self.useridText text]); int res = [appSafer setUserId:[self.useridText text]]; switch(res) { case FAIL: NSLog(@"Failed to set userId"); break; case SUCCESS: NSLog(@"setUserId Success"); break; } } else { NSLog(@"AppSafer is nil"); } }
appSaferDidInitFinish
initAppSafer 함수 호출 후 초기화 결과를 전달하기 위해 아래 함수가 호출됩니다.
func appSaferDidInitFinish(_ result: Int32)
- (void)appSaferDidInitFinish:(int)result
매개변수
매개변수 설명 SUCCESS(0) 초기화 성공 FAIL(-1) 초기화 실패 BLOCK(2) 보안 정책 위반으로 차단됨 예제
func appSaferDidInitFinish(_ result: Int32) { print("appSaferDidInitFinish result: \(result)"); if(result == BLOCK) { print("Device is blocked!"); // add to exit application logic } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDidInitFinish:(NSUInteger)result msg:(NSString *)message { NSLog(@"appSaferDidInitFinish result: %d", result); if(result == BLOCK) { NSLog(@"Device is blocked!"); // add to exit application logic } }
appSaferDidCheckTamperingFinish
checkTampering 함수의 수행 결과를 전달하기 위해 아래 함수가 호출됩니다.
func appSaferDidCheckTamperingFinish(_ result: Int32)
- (void)appSaferDidCheckTamperingFinish:(int)result
매개변수
매개변수 설명 FAIL(-1) 검사 실패 SAFE(0) 이벤트가 탐지되지 않음 DETECT(1) 이벤트 탐지 BLOCK(2) 차단됨 예제
func appSaferDidCheckTamperingFinish(_ result: Int32) { print("appSaferDidCheckTamperingFinish result: " + ( result == FAIL ? "FAIL" : result == SAFE ? "SAFE" : result == DETECT ? "DETECT" : result == BLOCK ? "BLOCK": "UNKNOWN")) if(result == BLOCK) { print("Device is blocked!") // add to exit application logic } }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDidCheckTamperingFinish:(int)result { NSLog(@"appSaferDidCheckTamperingFinish result: %@", result == FAIL ? @"FAIL" : result == SAFE ? @"SAFE" : result == DETECT ? @"DETECT" : result == BLOCK ? @"BLOCK": @"UNKNOWN"); if(result == BLOCK) { NSLog(@"Device is blocked!"); // add to exit application logic } }
appSaferDetectedJailbreak
기기의 탈옥이 탐지될 때 아래 함수가 호출됩니다. checkTampering 함수 동작이 완료되지 않았더라도 결과를 받고 싶을 때 사용할 수 있습니다.
func appSaferDetectedJailbreak()
- (void)appSaferDetectedJailbreak
예제
func appSaferDetectedJailbreak() { print("[DETECT] appSaferDetectedJailbreak"); }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDetectedJailbreak { NSLog(@"[DETECT] appSaferDetectedJailbreak"); }
appSaferDetectedSimulator
앱이 가상 머신에서 실행 중임이 탐지될 때 아래 함수가 호출됩니다. checkTampering 함수 동작이 완료되지 않았더라도 결과를 받고 싶을 때 사용할 수 있습니다.
func appSaferDetectedSimulator()
- (void)appSaferDetectedSimulator
예제
func appSaferDetectedSimulator() { print("[DETECT] appSaferDetectedSimulator"); }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDetectedSimulator { NSLog(@"[DETECT] appSaferDetectedSimulator"); }
appSaferDetectedDebugging
기기에서 디버깅이 탐지될 때 아래 함수가 호출됩니다. checkTampering 함수 동작이 완료되지 않았더라도 결과를 받고 싶을 때 사용할 수 있습니다.
func appSaferDetectedDebugging()
- (void)appSaferDetectedDebugging
예제
func appSaferDetectedDebugging() { print("[DETECT] appSaferDetectedDebugging"); }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDetectedDebugging { NSLog(@"[DETECT] appSaferDetectedDebugging"); }
appSaferDetectedMemoryTampered
메모리 변조가 탐지될 때 아래 함수가 호출됩니다. checkTampering 함수 동작이 완료되지 않았더라도 결과를 받고 싶을 때 사용할 수 있습니다.
func appSaferDetectedMemoryTampered()
- (void)appSaferDetectedMemoryTampered
예제
func appSaferDetectedMemoryTampered() { print("[DETECT] appSaferDetectedMemoryTampered"); }
#import <AppSaferFramework/AppSaferFramework.h> @implementation ViewController - (void)appSaferDetectedMemoryTampered { NSLog(@"[DETECT] appSaferDetectedMemoryTampered"); }