Data Sealing Java File I/O에서 NDK로 변환 가이드

AppSealing은 Data 파일을 암호화하여 보호하는 Data Sealing 기능을 제공합니다. Data Sealing을 이용하기 위해서는 아래의 파일 이름 규약을 따라야 하며, 현재 Native File I/O 함수만 지원합니다.

📌 Data Sealing 파일 이름 규약

00c6c7f4-42f0-4d57-8b1b-73704d93b42e.png

Data Sealing의 파일 이름 규약은 간단합니다. 파일 이름이 asdp_ 키워드로 시작하면, 해당 파일은 Data Sealing 대상 파일로 인식하여, 실링 이후에 데이터를 읽고 쓰는 과정에서 아래와 같이 암·복호화가 자동 반영됩니다. (res는 res/raw 디렉토리만 반영)

2604a6db-c15e-4326-98f5-73e089190667.png

 

📌 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());
}

 

도움이 되었습니까?
0명 중 0명이 도움이 되었다고 했습니다.
comment section

0 댓글

댓글을 남기려면 로그인하세요.