使用tiny-AES-c解密

发布于 2025-01-13 22:23:44 字数 1863 浏览 3 评论 0原文

我正在使用 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), 如果我尝试解密上面返回的值,它不会返回原始值,

.\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. 为什么对于相同的值+密钥+iv组合,加密值每次都会改变
  2. 为什么解密在第二个示例中起作用,而不是在单独加密和解密时起作用

I am using this c library, and have the following:

#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;
}

it gives an output of random characters when used like this:

.\example key msg
prints <random chars>  

The problem is that the chars given are different each run (with same iv),
if I try to decrypt the returned value from above, it won't return the original value

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

but if i use it like this:

#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;
}

this encrypts and decrypts the value.
it gives an output like this:

.\example key msg
enc: Vª≈  // encrypted (this changes every run)
dec: msg // decrypted
  1. why does the encrypted value change each time for the same value+key+iv combination
  2. why does the decryption work in the second example, and not when encrypting and decrypting separately

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我要还你自由 2025-01-20 22:23:44

您不能以这种方式使用密码作为密钥。如果您有人工输入的密码(例如“key”),则需要使用 PBKDF(例如 PBKDF2)将其转换为密钥。请参阅 http://bxr.su/OpenBSD/lib/libutil/pkcs5_pbkdf2.c #77 用于 C 和 https://en.wikipedia.org/wiki/PBKDF2 了解该算法的描述。

在您的代码中,您使用的密钥是 0x6b 0x65 0x79 0x00 ("key\0"),后跟内存中 argv[1] 之后的一些半随机垃圾字节。这就是为什么你每次都会得到不同的结果。 (垃圾字节的数量取决于您编译到 Tiny AES 中的密钥大小。默认密钥大小为 128 位,因此它将拾取 12 字节的垃圾数据。)

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

You cannot use a password as a key this way. If you have a human-typable password (such as "key"), you need to convert that to a key using a PBKDF such as PBKDF2. See http://bxr.su/OpenBSD/lib/libutil/pkcs5_pbkdf2.c#77 for an example implementation in C and https://en.wikipedia.org/wiki/PBKDF2 for a description of the algorithm.

In your code, the key you're using is 0x6b 0x65 0x79 0x00 ("key\0") followed by some number of semi-random garbage bytes that happened to be after argv[1] in memory. That's why you get different results every time. (The number of garbage bytes depends on what key size you compiled into Tiny AES. The default key size is 128 bits, so it'll pick up 12 bytes of garbage data.)

Also, even with a proper key, the output content will be unprintable. It will be a series of bytes with values between 0 and 255. Many of those values cannot be printed on a terminal, and as you've written it, you'll keep printing until you find the first zero (which will be at a random location, possibly somewhere inside the ciphertext, possibly after it). In order to print cipher text, you need to encode it somehow, such as Base64 or Hex. Tiny AES has no features for any of this; that's part of why it's so tiny. It just does the most basic AES encryption and decryption. Everything else is up to you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文