使用 tiny-AES-c 解密

decrypting using tiny-AES-c

我正在使用 this c 库,并且具有以下内容:

#include <stdio.h>
#include <string.h>
#include "aes.h"

int main(int argc, char *argv[]) {

  if (argc < 3) return 1;

  uint8_t *key = argv[1];

  uint8_t *content = argv[2];

  uint8_t iv[16] = { 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,0x0f,0x0f};

  struct AES_ctx ctx;

  AES_init_ctx_iv(&ctx, key, iv);
  AES_CTR_xcrypt_buffer(&ctx, content, strlen(content));

  printf("%s", (char*) content);
  return 0;
}

像这样使用时它会给出随机字符的输出:

.\example key msg
prints <random chars>  

问题是给定的字符每个 运行 不同(具有相同的 iv), 如果我尝试从上面解密 returned 值,它不会 return 原始值

.\example key <random chars>  
prints more random chars

但如果我这样使用它:

#include <stdio.h>
#include <string.h>
#include "aes.h"

int main(int argc, char *argv[]) {

  if (argc < 3) return 1;

  uint8_t *key = argv[1];

  uint8_t *content = argv[2];

  uint8_t iv[16] = { 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,0x0f,0x0f};

  struct AES_ctx ctx;

  AES_init_ctx_iv(&ctx, key, iv);
  AES_CTR_xcrypt_buffer(&ctx, content, strlen(content));

  printf("enc: %s\n", (char*) content);

  AES_init_ctx_iv(&ctx, key, iv);
  AES_CTR_xcrypt_buffer(&ctx, content, strlen(content));

  printf("dec: %s", (char*) content);
  return 0;
}

这会加密和解密值。 它给出了这样的输出:

.\example key msg
enc: Vª≈  // encrypted (this changes every run)
dec: msg // decrypted
  1. 为什么相同的value+key+iv组合每次加密后的值都变了
  2. 为什么在第二个示例中解密有效,而不是在单独加密和解密时无效

您不能以这种方式使用密码作为密钥。如果您有 human-typable 密码(例如“key”),则需要使用 PBKDF(例如 PBKDF2)将其转换为密钥。有关算法的说明,请参阅 http://bxr.su/OpenBSD/lib/libutil/pkcs5_pbkdf2.c#77 for an example implementation in C and https://en.wikipedia.org/wiki/PBKDF2

在您的代码中,您使用的密钥是 0x6b 0x65 0x79 0x00 ("key[=21=]"),后跟一些 semi-random 垃圾字节,恰好在 [=10= 之后] 在记忆中。这就是为什么你每次都会得到不同的结果。 (垃圾字节数取决于您编译成 Tiny AES 的密钥大小。默认密钥大小为 128 位,因此它将拾取 12 字节的垃圾数据。)

此外,即使使用正确的密钥,输出 content 也将无法打印。它将是一系列值介于 0 和 255 之间的字节。其中许多值无法在终端上打印,并且正如您编写的那样,您将继续打印直到找到第一个零(它将位于随机位置,可能在密文内部的某处,可能在它之后)。为了打印密文,您需要以某种方式对其进行编码,例如 Base64 或 Hex。 Tiny AES 没有这些功能;这就是为什么它这么小的部分原因。它只是做最基本的AES加密和解密。其他一切由你决定。