AES_encrypt/AES_decrypt 仅返回消息的一部分

use*_*061 5 java-native-interface openssl

我不知道为什么下面的代码会返回“Hello native!Th”而不是“Hello native!This is from jni load!\n”,有人可以提示一下吗?

#include "helloJNI.h"
#include "openssl/aes.h"

#define LEN 1024

jstring jni_text(JNIEnv *env, jclass clz)
{
    AES_KEY aesKey;
    int result;
    const char origin[] = "Hello native! This is from jni load!\n";
    char out[LEN];
    char outout[LEN];
    memset(out, '\0', sizeof(out));
    memset(outout, '\0', sizeof(outout));
    result = AES_set_encrypt_key((const unsigned char *)"abc123", 256, &aesKey);
    LOGE("encypt key result %d\n", result); /* is 0 */
    AES_encrypt((const unsigned char *)origin, (unsigned char *)out, &aesKey);
    LOGE("after encrypt, chars is %s\n", out);
    result = AES_set_decrypt_key((const unsigned char *)"abc123", 256, &aesKey);
    LOGE("decrypt key result %d\n", result); /* is 0 */
    AES_decrypt(out, outout, &aesKey);
    LOGE("after decrypt, chars is %s\n", outout);
    return (*env)->NewStringUTF(env, outout); /* return "Hello native! Th" */
}
Run Code Online (Sandbox Code Playgroud)

jww*_*jww 4

AES_encrypt((const unsigned char *)origin, (unsigned char *)out, &aesKey);

AES_encrypt在 16 字节块上运行。16是AES的块大小。

实际上,您截断了您的消息。

AES_decrypt(pout, outout, &aesKey);

在这里,您只解密了 16 个字节。缓冲区的剩余部分用 0 回填。0 用作 ASCII-Z 终止符。


您正在 ECB 模式下有效地操作密码。ECB 模式可能不适合您的需求。仅当一条消息使用一个密钥加密时,ECB 模式才是安全的。否则,攻击者就会得知同一条消息被加密了两次。

此外,只有消息小于块大小时才安全。如果消息大于块大小,则 ECB 模式可能会泄漏信息。


您可能应该使用 CBC 模式。您还应该使用EVP_*函数而不是AES_encryptand AES_decrypt。请参阅OpenSSL wiki 上的EVP 对称加密和解密。

如果您只是加密数据,那么您就缺乏完整性和真实性保证。所以密文是可塑的,这通常是一件坏事。在这种情况下,最好使用 EAX、CCM 或 GCM 等模式。为此,请参阅EVP 验证加密和解密