Search code examples
javacjava-native-interfacesgx

How to encrypt java Strings in C considering their size difference?


Good evening, I am building a java project in which it communicates with an Intel SGX Enclave via JNI, and sees information it sends sealed by the enclave.

However, decrypting information returns information I cannot understand, and at this point, I believe it to be due to size differences,but I dont exactly understand it.

So, I know that Sizeof(char*) is equivalent to 1 byte, just like sizeof(jbyte). However, sizeof(jchar) is equivalent to 2 bytes.

After acquiring this knowledge, I decided to implement the Sealing (Or encryption) function by having it take a JByteArray in order to circumvent this problem. Should this byte[] be given in UTF-8 or UTF-16? Does it affect the function overall?

Here is an example of what I do:

JNIEXPORT jbyteArray JNICALL Java_sgxUtils_SgxFunctions_jni_1sgx_1seal_1info
  (JNIEnv * env, jobject, jbyteArray jArray){
    
   //Create a char* from the given byte array.   
   jbyte *b = env->GetByteArrayElements(jArray,NULL);
   int StringSize = env->GetArrayLength(jArray);
   char* c = (char*)malloc(sizeof(char) * StringSize);
   memcpy(c,b,StringSize);
   
   //Calculate the size of the encryption.
   size_t sealed_size = sizeof(sgx_sealed_data_t) + StringSize;

   //Create a uint8_t pointer to store the sealed information
   uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);

   sgx_status_t ecall_status; //Store the status of the ecall.
   seal(global_eid, &ecall_status,(uint8_t*)&c,StringSize, sgx_sealed_data_t*)sealed_data,sealed_size);

   //Produce the jbyteArray to return:
    jbyte* jresult = (jbyte*)calloc(sizeof(jbyte),sealed_size);
    for(int i = 0 ; i < sealed_size ;i++){
        jresult[i] = (jbyte)sealed_data[i];
    }

    jbyteArray jArray2 = env->NewByteArray(sealed_size+1);
    env->SetByteArrayRegion(jArray2,0,sealed_size,jresult);
    
    return jArray2;

Does using uint8_t affect the sealing? I am at a loss of what it might be. The way I receive this byte[] in java is as follows:

byte[] c = sgx.jni_sgx_seal_info("toEncrypt".getBytes(Charset.forName("UTF-8")));
String sealed = new String(c,StandardCharsets.UTF_8);

Does anyone know what could be affecting this? The output after unsealing (decryption) currently stands as �|(�


Solution

  • You can't convert random bytes (such as produced by encryption) into UTF-8 (or many multi-byte encodings, 8-bit single byte encodings are fine). The String will most likely become corrupted, as there are byte sequences describing illegal characters, they will be replaced with 0xFFFE or i.e. he unicode replacement character.

    So you will need to keep the byte[] around and not convert that to a String until you've decrypted the byte array, not a String.