📌데이터실링 지원 환경
- 앱실링 버전2.23.0.0부터 지원합니다.
- Data Sealing은 리소스/Data 파일을 암호화하여 보호하는 기능입니다.
- 데이터 실링 기능은 현재 Android Native C/C++(NDK) 에서만 지원합니다. 따라서 다른 프레임워크(예: Java/Kotlin, Unity, Flutter) 에서는 기본적으로 이용이 가능하지 않습니다. 대신 이러한 프레임워크에서 Native C/C++와 연동할 수 있는 플러그인을 지원한다면 이를 통하여 Data Sealing 기능을 적용할 수 있습니다.
- Data Sealing을 이용하기 위해서는 아래의 파일 이름 규약을 따라야 합니다.
📌 Data Sealing 파일 이름 규약
Data Sealing의 파일 이름 규약은 간단합니다. 파일 이름이 asdp_ 키워드로 시작하면, 해당 파일은 Data Sealing 대상 파일로 인식하여, 실링 이후에 데이터를 읽고 쓰는 과정에서 아래와 같이 암·복호화가 자동 반영됩니다. (res는 res/raw 디렉토리만 반영)
📌 Native File I/O 지원
Data Sealing은 현재 Native File I/O 함수만 지원합니다. 따라서,Java/Kotlin으로 개발된 환경에서는 파일 입출력 파트를 NDK(C/C++) 환경으로 변환하여 사용해야 합니다. 지원하는 Native File I/O 함수들은 다음과 같습니다.
- fopen 계열 File I/O 지원
fopen
fseek
ftell
fread
fwrite
fclose
- AAsset 계열 지원
AAssetManager_open
AAsset_getBuffer
AAsset_getLength
AAsset_getLength64
AAsset_getRemainingLength
AAsset_getRemainingLength64
AAsset_read
AAsset_seek
AAsset_seek64
AAsset_close
📌 Java를 NDK(Native C/C++)로 변환하는 기본 예제
Native File I/O 파일 읽기 예제
- Java (Java는 Data Sealing 지원하지 않으므로, 아래 Java 코드는 Data Sealing 적용되지 않음)
/**
* FileInputStream을 이용하여 파일 읽기
*
* @param filePath (ex) asdp_sample.txt
* @return
*/
public String getFileText(String filePath) {
String dataText = "";
FileInputStream fileStream = null;
try {
fileStream = new FileInputStream(filePath);
byte[] buffer = new byte[fileStream.available()];
int count = fileStream.read(buffer);
if (count > 0) {
dataText = new String(buffer, 0, count);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fileStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return dataText;
}
- NDK(C/C++)
/**
* fopen을 이용하여 파일 읽기
*
* @param env jni function default parameter
* @param cls jni function default parameter
* @param filePath (ex) asdp_sample.txt
* @return
*/
extern "C" JNIEXPORT jstring JNICALL
Java_com_appsealing_datasealing_test_TestNative_getFileText(JNIEnv* env,
jobject cls,
jstring filePath)
{
const char* testPath = env->GetStringUTFChars(filePath, 0);
FILE * fp = fopen(testPath, "rb");
env->ReleaseStringUTFChars( filePath, testPath );
if(fp == NULL)
{
LOGE("File fopen failed.");
// File open failed
return env->NewStringUTF("");
}
fseek(fp, 0, SEEK_END); // 파일 포인터를 파일의 끝으로 이동시킴
int size = ftell(fp); // 파일 전체 길이를 구함
char buffer[10240] = { 0x00, };
int len;
fseek(fp, 0, SEEK_SET); // 파일 포인터를 파일의 처음으로 이동시킴
len = fread(buffer, size, 1, fp);
LOGD("%s size: %d, len: %d\n", buffer, size, len);
std::string dataText = buffer;
fclose(fp);
return env->NewStringUTF(dataText.c_str());
}
Native AAsset 파일 읽기 예제
- Java (Java는 Data Sealing 지원하지 않으므로, 아래 Java 코드는 Data Sealing 적용되지 않음)
/**
* AssetManager를 이용하여 파일 읽기
*
* @param assetName (ex) asdp_sample.txt
* @return
*/
public String getAssetFileText(String assetName) {
String assetText = "";
AssetManager assetManager = context.getAssets();
InputStream stream = null;
try {
stream = assetManager.open(assetName);
byte buffer[] = new byte[stream.available()];
if (stream.read(buffer) > 0) {
assetText = new String(buffer);
}
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
return assetText;
}
- NDK(C/C++)
/**
* AAssetManager를 이용하여 파일 읽기
*
* @param env jni function default parameter
* @param cls jni function default parameter
* @param assetManager (ex) java:context.getAssets()
* @param assetName (ex) asdp_sample.txt
* @return
*/
extern "C" JNIEXPORT jstring JNICALL
Java_com_appsealing_datasealing_test_TestNative_getAssetFileText(
JNIEnv* env,
jobject cls,
jobject assetManager,
jstring assetName) {
const char* temp = env->GetStringUTFChars(assetName, 0);
std::string asset_name = temp;
env->ReleaseStringUTFChars( assetName, temp );
AAssetManager* am = AAssetManager_fromJava(env, assetManager);
AAsset* asset = AAssetManager_open(am, asset_name.c_str(), AASSET_MODE_UNKNOWN);
if (asset == NULL)
return env->NewStringUTF("");
int fileSize = AAsset_getLength(asset);
if (fileSize == 0)
return env->NewStringUTF("");
std::string assetText(fileSize + 1, 0x00);
AAsset_read(asset, (void*)assetText.data(), fileSize);
AAsset_close(asset);
return env->NewStringUTF(assetText.c_str());
}