GMP库中的gmp_fscanf无法正确读取十六进制输入

时间:2014-10-26 17:30:19

标签: c gmp

我目前正在尝试读取我的代码输出的密钥文件,以获取 RSA-2048 的示例实现。

我的输出代码如下:

void generate_rsa_key(arguments args) {
  FILE* fp_pub;
  fp_pub = fopen("rsa_key.pub", "wb");

  FILE* fp_pri;
  fp_pri = fopen("rsa_key.pri", "wb");

  rsa_keygen(args.m_n, args.m_pri_exp, args.m_pub_exp);

  gmp_fprintf(fp_pub, "%ZX.%ZX", args.m_pub_exp, args.m_n);
  gmp_fprintf(fp_pri, "%ZX.%ZX", args.m_pri_exp, args.m_n);

  fprintf(stdout, "\nRSA key pair generated.\n\n");
}

导致十六进制编码的输出看起来像:

10001.9F959C28250AF2197AE7B1638AA1CC464B4D4E091B2182830D4020267F68D1DDDBB7E8E1039
C9CEDFE6FD58BA0CA4E16D47D586CC66C2D86DCD3171D7CB5B7A12EDBAEC9E6FB944094519D9A6EAC
7CD6D43B1E1EA8C068FAA3BD0C9C4A703FF6A72782C4A3C8214BCECA8FF9F7B044D51ECB6B11DEB3B
80D0835B6518669742EDC116EF929334DF647A59D2AF395BDBECB6DA74C660B1DAF3D4C25432C6B11
D9C4A6A5D29302D50039F15B1850ED57DA7F9C701BA18141A9E0A6761E88B59E1A01C908A60E4A143
EDC67DE94AD8132305F9B28F2AA3B581E9BE0336D3B34AD0D874B92C51E9A2C074608EB3CD0119CC8
6701BA9667FC1AE00CBEC2DE8932DCEF

我在密钥文件中读取的代码是:

typedef struct arguments {
  mpz_t m_pri_exp;
  mpz_t m_pub_exp;
  mpz_t m_n;
  mpz_t o_pub_exp;
  mpz_t o_n;
} arguments;

void read_rsa_keyfile(char* path, arguments args, int pri) {
  FILE *fp;
  fp = fopen(path, "rb");

  if (pri) {
    gmp_fscanf(fp, "%ZX.%ZX", args.m_pri_exp, args.m_n);
  } else {
    gmp_fscanf(fp, "%ZX.%ZX", args.o_pub_exp, args.o_n);
  }
}

arguments parse_args(int argc, char* argv[]) {
  int i;
  arguments args;

  for (i = 0; i < argc; i++) {
    if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gen-key")) {
      mpz_inits(args.m_pri_exp, args.m_pub_exp, args.m_n, NULL);
      generate_rsa_key(args);
      exit(-1);

    } else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--my-key-file")) {
      read_rsa_keyfile(argv[i+1], args, T);

    } else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--other-key-file")) {
      read_rsa_keyfile(argv[i+1], args, F);

    } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
      print_help();
    }
  }

  if (!mpz_cmp_ui(args.m_pri_exp, (unsigned long)0) || \
      !mpz_cmp_ui(args.m_n, (unsigned long)0) ||       \
      !mpz_cmp_ui(args.o_pub_exp, (unsigned long)0) || \
      !mpz_cmp_ui(args.o_n, (unsigned long)0)) {
    print_help();
  } else {
    return args; 
  }
}

请注意,我没有初始化mpz_t变量,并且我为gmp_fscanf调用提供变量本身而不是地址,这两个变量都与GMP docs一致。

但是,当我运行代码时,它会在GMP库中进行段错误,并提供错误输出:

*** glibc detected *** ./dhe_rsa: realloc(): invalid pointer: 0x00007fff9c0342b8 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76a16)[0x7fe3dfb1da16]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x312)[0x7fe3dfb23c22]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_default_reallocate+0x1c)[0x7fe3e009ca1c]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_realloc+0x3a)[0x7fe3e00b2bba]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_set_str+0x301)[0x7fe3e00b3ef1]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_doscan+0xda7)[0x7fe3e00ed777]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_fscanf+0x94)[0x7fe3e00ed8c4]
./dhe_rsa[0x40164f]
./dhe_rsa[0x400fa9]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7fe3dfac5ead]
./dhe_rsa[0x4011b1]

我的代码有什么问题吗?在我看来,正确匹配文档中的内容。我已经尝试了许多不同的东西来尝试和调试它,并没有得到任何地方。

修改

正如Grzegorz Szpetkowski指出的那样,我误解了文档,我确实需要初始化变量。但是,我认为变量不需要初始化的原因是我的fscanf读取结果为0。因此,现在是我的问题。我已将我的功能编辑为:

arguments parse_args(int argc, char* argv[]) {
  int i;
  arguments args;

  mpz_inits(args.m_pri_exp, args.m_pub_exp, args.m_n, args.o_pub_exp, args.o_n, NULL);

  for (i = 0; i < argc; i++) {
    if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gen-key")) {
      generate_rsa_key(args);
      exit(-1);

    } else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--my-key-file")) {
      read_rsa_keyfile(argv[i+1], args, T);

    } else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--other-key-file")) {
      read_rsa_keyfile(argv[i+1], args, F);

    } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
      print_help();
    }
  }

  gmp_fprintf(stdout, "%ZX\n", args.m_pri_exp);
  gmp_fprintf(stdout, "%ZX\n", args.m_n);
  gmp_fprintf(stdout, "%ZX\n", args.o_pub_exp);
  gmp_fprintf(stdout, "%ZX\n", args.o_n);

  if (!mpz_cmp_ui(args.m_pri_exp, (unsigned long)0) || \
      !mpz_cmp_ui(args.m_n, (unsigned long)0) ||       \
      !mpz_cmp_ui(args.o_pub_exp, (unsigned long)0) || \
      !mpz_cmp_ui(args.o_n, (unsigned long)0)) {
    print_help();
  } else {
    return args; 
  }
}

我得到了输出:

0
0
0
0

其余的保持不变。

1 个答案:

答案 0 :(得分:1)

出现问题并不明显,因为我们不知道如何调用程序并且缺少代码片段。但是,对我来说非常清楚的是,您仅为第一个选项(mpz_inits()-g)调用--gen-key函数。由于有exit(-1)电话,很明显其他选项缺少必要的初始化(read_rsa_keyfile()显然是这样的候选者)。要对mpz_t个对象执行任何操作,您必须先对其进行初始化。