我正在使用gmp进行项目以实现基本的DH交换。此交换有两个主要功能,一个是从私有密钥创建一个公共密钥,另一个是通过私有密钥和公共密钥生成共享密钥。
在第一个函数中,我对gmp lib的调用按预期工作。在第二个函数中,我的mpz_init_set_str调用要么导致段错误,要么中止并显示消息
realloc():旧大小无效 中止(核心已弃用)
或
malloc.c:2868:mremap_chunk:断言`(((size + offset)&(GLRO(dl_pagesize)-1))== 0'失败。
导致此问题的行在第一个函数中被逐字使用,我无法弄清楚是什么原因造成的。
下面是一个示例程序,该示例程序在我的计算机上运行时演示了该问题。 我正在使用gcc(Ubuntu 7.4.0-1ubuntu1〜18.04.1)7.4.0。和libgmp10版本2:6.1.2 + dfsg-2
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "gmp.h"
#include "time.h"
#define SECRET_KEY_SIZE 64
#define PRIVATE_KEY_SIZE 512
#define DH_KEY_EXCHANGE_P "96C99B60C4F823707B47A848472345230C5B25103DC37412A701833E8FF5C567A53A41D0B37B10F0060D50F4131C57CF1FD11B6A6CB958F36B1E7D878A4C4BC7"
#define DH_KEY_EXCHANGE_G "2C900DF142E2B839E521725585A92DC0C45D6702A48004A917F74B73DB26391F20AEAE4C6797DD5ABFF0BFCAECB29554248233B5E6682CE1C73DD2148DED76C3"
#define BASE_HEX 16
#define BASE_RADIX 32
char intToCharBase32(int input)
{
char ret = 0;
if(input <= 9)
{
ret = '0' + input;
}
else if(input < 32)
{
ret = (input - 10) + 'A';
}
return ret;
}
void generateRandomKey(char *random_number_buffer, int len)
{
short int n;
srand(time(0));
for(int i=0; i<len; i++)
{
n = rand() % BASE_RADIX;
random_number_buffer[i] = intToCharBase32(n);
}
random_number_buffer[len] = '\0';
}
void calculateDHPublicKey(char *public_key, char *private_key)
{
mpz_t p;
mpz_t g;
mpz_t b;
mpz_t B;
mpz_init (B);
mpz_init_set_str (p, DH_KEY_EXCHANGE_P, BASE_HEX);
mpz_init_set_str (g, DH_KEY_EXCHANGE_G, BASE_HEX);
mpz_init_set_str (b, private_key, BASE_RADIX);
mpz_powm (B, g, b, p);
mpz_get_str(public_key, BASE_RADIX, B);
mpz_clear (p);
mpz_clear (g);
mpz_clear (b);
mpz_clear (B);
}
void calculateDHSharedSecret(unsigned char *dh_key_buffer, char *own_private_key, char *other_public_key)
{
mpz_t p;
mpz_t b;
mpz_t A;
mpz_t SS;
mpz_init (SS);
mpz_init_set_str (p, DH_KEY_EXCHANGE_P, BASE_HEX); // <--This line crashes
mpz_init_set_str (b, own_private_key, BASE_RADIX);
mpz_init_set_str (A, other_public_key, BASE_RADIX);
mpz_powm (SS, A, b, p);
size_t size = 0;
//todo: move this to the right place (add leading zeros as needed);
mpz_export(dh_key_buffer, &size, 1, -1, 0, 0, SS);
mpz_clear (p);
mpz_clear (b);
mpz_clear (A);
mpz_clear (SS);
}
int main (){
char* private_key = malloc(sizeof(char) * (PRIVATE_KEY_SIZE / BASE_RADIX + 2));
generateRandomKey(private_key, PRIVATE_KEY_SIZE / BASE_RADIX);
fprintf(stderr, "Private Key: %s\n", private_key);
//step 2: generate public key
char* public_key = malloc(sizeof(char) * (2048 / BASE_RADIX + 1));
calculateDHPublicKey(public_key, private_key);
//step 3: share the public key
fprintf(stderr, "Public Key: %s\n", public_key);
//step 4: Calculate shared secret
unsigned char* sharedSecret = malloc(sizeof(unsigned char) * SECRET_KEY_SIZE);
memset(sharedSecret, 0, SECRET_KEY_SIZE);
char* other_pk = "1";
//for debugging just use 1 as the other side of dh handshake
calculateDHSharedSecret(sharedSecret, private_key, other_pk);
//step 5: release resources
free(private_key);
free(public_key);
return 0;
}
我尝试使用mpz_init,然后使用mpz_set_str而不是mpz_init_set_str,并且该功能仍然中止。
我能够使用mpz_init2并提供初始大小作为解决方法,但是在我的项目后面,我将不知道所需的大小,因此希望避免将其确定为额外的步骤。
(我很清楚,生成随机密钥的方法要好得多,并且rand()在密码上是不安全的,但是该项目将用于演示此问题以及其他常见的安全问题)< / p>