AES_encrypt / AES_decrypt仅返回部分消息

时间:2015-04-24 02:42:18

标签: openssl java-native-interface

我不知道为什么下面的代码会返回" Hello native!个"不是"你好原生!这是来自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" */
}

2 个答案:

答案 0 :(得分: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模式才是安全的。否则,攻击者会得知相同的邮件已加密两次。

此外,它唯一的安全 if 消息小于块大小。如果消息大于块大小,则ECB模式可能泄漏信息。

你应该使用CBC模式。您还应该使用EVP_*函数而不是AES_encryptAES_decrypt。请参阅OpenSSL wiki上的EVP Symmetric Encryption and Decryption

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

答案 1 :(得分:2)

每次调用AES_encrypt都会加密一个AES块... 16个字节。这就是为什么通过一次通话,您的加密缓冲区中只有16个字符结束。