如何将加密数据从 C++ 传输到 java
How to transfer encrypt data from c++ to java
我有一个使用 JNI(JAVA , C++ 的简单加密程序。
简要地 :
我将一个简单的字符串传递给 C++ 程序。
C++ 程序为我和 return 密码字符串加密该字符串。
我会为客户打印密文。
问题:
当我用 C++ 加密并将其传递给 java 时,某些字符无法传输。
但是当我使用 C++ 控制台打印它时,它是正确的。
该字符之一是:
â , ü
C++ 控制台中的密文:
ozmzâx~w|(~i}|64ío(üuvt*po~,s|*nY|(yy~(ktztskk|sgX
在java中传输的密文:
ozmz?x~w|(~i}|64ío(?uvt*po~,s|*nY|(yy~(ktztskk|sgX
(â , ü is lost)
因此,由于这个错误,当我想解密文本时,这些字符无法正确解密(但在 C++ 中正确解密!)
纯文本:
Hello, This is a test message for encryptor test, we will test it for
our application
密文java:
Rmvpy4*Prq},su~m}xuos}iqirybozmz?x~w|(~i}|64ᄀo(?uvtpo~,s|*nY|(yy|
(ktztskk|sgX
解密文本:
Hello, This is a test message for encrケptor test, キe キill test it
for our
application
(在 "encryptor" 和 "we" 和 "will" 中失败)
我能做什么?
我以 jbyteArray 格式将字符从 C++ 传输到 java。
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,默认情况下是 orbiter,而其他实现则需要您自己 encoding/decoding。
加密是基于字节的,而不是字符,并非所有字节值都可以是 displayed/are 个字符。解决方案是将加密的二进制数据编码为字符编码,例如 ASCII,两种主要方法是表示二进制字节的两种常用方式,因此它们可以显示:Base64 (good for computers) and Hexadecimal(对开发人员有利)..
-更多-
二字显示:
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个字符。这将加密 tp 96 个字符。加密文本显示 50 个字符,因此缺少 46 个字节,这些是没有可显示值的字节值 and/or 显示提前终止。
我有一个使用 JNI(JAVA , C++ 的简单加密程序。 简要地 : 我将一个简单的字符串传递给 C++ 程序。 C++ 程序为我和 return 密码字符串加密该字符串。 我会为客户打印密文。
问题: 当我用 C++ 加密并将其传递给 java 时,某些字符无法传输。 但是当我使用 C++ 控制台打印它时,它是正确的。 该字符之一是:
â , ü
C++ 控制台中的密文:
ozmzâx~w|(~i}|64ío(üuvt*po~,s|*nY|(yy~(ktztskk|sgX
在java中传输的密文:
ozmz?x~w|(~i}|64ío(?uvt*po~,s|*nY|(yy~(ktztskk|sgX
(â , ü is lost)
因此,由于这个错误,当我想解密文本时,这些字符无法正确解密(但在 C++ 中正确解密!)
纯文本:
Hello, This is a test message for encryptor test, we will test it for our application
密文java:
Rmvpy4*Prq},su~m}xuos}iqirybozmz?x~w|(~i}|64ᄀo(?uvtpo~,s|*nY|(yy| (ktztskk|sgX
解密文本:
Hello, This is a test message for encrケptor test, キe キill test it for our application
(在 "encryptor" 和 "we" 和 "will" 中失败) 我能做什么?
我以 jbyteArray 格式将字符从 C++ 传输到 java。
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,默认情况下是 orbiter,而其他实现则需要您自己 encoding/decoding。
加密是基于字节的,而不是字符,并非所有字节值都可以是 displayed/are 个字符。解决方案是将加密的二进制数据编码为字符编码,例如 ASCII,两种主要方法是表示二进制字节的两种常用方式,因此它们可以显示:Base64 (good for computers) and Hexadecimal(对开发人员有利)..
-更多-
二字显示:
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个字符。这将加密 tp 96 个字符。加密文本显示 50 个字符,因此缺少 46 个字节,这些是没有可显示值的字节值 and/or 显示提前终止。