У меня есть простая программа шифрования, использующая JNI(JAVA, C ++.
Вкратце:
Я передаю простую строку в программу C ++.
Программа C ++ зашифровывает эту строку для меня и возвращает строку шифра.
Я напечатаю зашифрованный текст для клиента.
Проблема:
Когда я шифрую в c ++ и передаю его Java, некоторые символы не могут быть переданы.
но когда я печатаю это, используя консоль c ++, это правильно.
один из этих персонажей:
â, ü
зашифровать текст в консоли C ++:
ozmzâx ~ ш | (~ г} | 64ío (üuvt * ро ~, с | * Ny | (уу ~ (ktztskk | SGX
зашифрованный текст, который был переведен в Java:
ozmz х ~ ш |? (~ я} |? 64ío (УВТ * ро ~, с | * Ny | (уу ~ (ktztskk | SGX
(â, ü потеряно)
Поэтому из-за этой ошибки, когда я хочу расшифровать текст, эти символы не расшифровываются правильно (но в c ++ расшифровываются правильно!)
простой текст :
Здравствуйте, это тестовое сообщение для теста шифра, мы проверим его
наше приложение
зашифровать текст java:
Rmvpy4 * PRQ}, си ~ т} хУОС} IQIrybozmz х ~ ш |? (~ я} |? 64 ㄱ о (УВТро ~, с | * Ny | (уу |
(Ktztskk | SGX
расшифровать текст:
Здравствуйте! Это тестовое сообщение для теста encr ケ ptor.
за наших
приложение
(ошибка в «encryptor» и «мы» и «будет»)
А что я могу сделать?
Я передаю символы из c ++ в java в формате jbyteArray.
C ++ КОД:
JNIEXPORT jbyteArray JNICALL Java_com_mf_dems_HelloJNI_encryptTest
(JNIEnv *env, jobject thisObject, jobject encryptorContext, jstring
jInputBlock)
{
//get class
jclass encryptorContextClass = env->GetObjectClass(encryptorContext);
//get keyLength
jfieldID keyLengthFieldId = env->GetFieldID(encryptorContextClass,
"keyLength", "I");
jint keyLength = env->GetIntField(encryptorContext, keyLengthFieldId);
//get blockLength
jfieldID blockLengthFieldId = env->GetFieldID(encryptorContextClass,
"blockLength", "I");
jint blockLength = env->GetIntField(encryptorContext, blockLengthFieldId);
//get key
jfieldID keyFieldId = env->GetFieldID(encryptorContextClass, "key", "[C");
jobject jKeyArray =env->GetObjectField(encryptorContext, keyFieldId);
jchar *key =env->GetCharArrayElements((jcharArray)(jKeyArray), NULL);
//get inputBlock
const jchar *inputBlock = env->GetStringChars(jInputBlock, NULL);
jbyte *buf = new jbyte[blockLength];
unsigned int i=0;
for(i ; i< blockLength ; i++)
{
buf[i] =((inputBlock[i] +10) ^ key[i] ^ key[i+15] ^ 0x11);
}
env->ReleaseStringChars(jInputBlock, inputBlock);
env->ReleaseCharArrayElements((jcharArray)(jKeyArray), key, 0);
jbyteArray jOut = env->NewByteArray(blockLength);
env->SetByteArrayRegion(jOut, 0, blockLength, buf);
delete [] buf;
return jOut;
}
КОД JAVA:
EncryptorContext encryptorContext = new EncryptorContext();
encryptorContext.setBlockLength(17);
encryptorContext.setKeyLength(32);
encryptorContext.setKey(new char[encryptorContext.getKeyLength()]);
String plainText = "Hello, This is a test message for encryptor test, we will test it for our application.";
String cipherText = "";
//set key
for (int i = 0; i < encryptorContext.getKeyLength(); i++) {
encryptorContext.getKey()[i] = (char) (i + 1);
}
//ENCRYPT
for (int i = 0; i < (plainText.length() -encryptorContext.getBlockLength()); i +encryptorContext.getBlockLength())
{
byte [] out = helloJNI.encryptTest(encryptorContext,
plainText.substring(i, i + encryptorContext.getBlockLength()));
byte[] latin1 = new String(out, "ISO-8859-1").getBytes("UTF-8");
for (byte b : out) {
cipherText+=(char)b;
}
}
System.out.println(cipherText);
Решение состоит в том, чтобы зашифровать вывод в символьную кодировку. При расшифровке сначала декодируйте обратно в двоичный файл. Некоторые реализации шифрования обрабатывают Base64 с опцией, орбитальный аппарат по умолчанию и другие, вам потребуется самостоятельно выполнить кодирование / декодирование.
Шифрование основано на байтах, а не на символах, не все байтовые значения могут быть отображены / являются символами. Решение состоит в том, чтобы закодировать зашифрованные двоичные данные в кодировке символов, такой как ASCII, двумя основными способами являются два распространенных способа представления двоичных байтов, чтобы они отображались: Base64 (хорошо для компьютеров) и шестнадцатеричный (хорошо для разработчиков) ..
-Больше-
Отображение двух символов:
ozmzâx~w|(~i}|64ío(üuvt*po~,s|*nY|(yy~(ktztskk|sgX
ozmz?x~w|(~i}|64ío(?uvt*po~,s|*nY|(yy~(ktztskk|sgX
различаются, потому что две системы используют немного разные символы для некоторых значений байтов, нижняя использует ?
для значений у него нет символа для.
Простой текст состоит из 86 символов, а отступы — из 96 символов. Это зашифрует 96 символов. Зашифрованный текст отображает 50 символов, поэтому 46 байтов отсутствуют, это байтовые значения без отображаемого значения и / или преждевременное завершение отображения.
Других решений пока нет …