【问题标题】:Generate every time same RSA key with c++每次使用 C++ 生成相同的 RSA 密钥
【发布时间】:2019-04-30 19:37:38
【问题描述】:

我尝试每次使用 RSA_generate_key_ex(...) 生成相同的 RSA 密钥,然后写入文件,但我总是得到不同的密钥。是否有任何交钥匙解决方案,或者我需要为此编写自己的函数? (我知道这是不安全的解决方案)

char *passW = "password";
RSA *rsa = RSA_new();

BIGNUM *bn = BN_new();
BN_bn2bin(bn, (unsigned char *)passW);
BN_set_word(bn, RSA_3);

OpenSSL_add_all_algorithms();
RSA_generate_key_ex(rsa, 1024, bn, nullptr); 

/* Save private key */
FILE* fp = fopen("private.key", "w");
PEM_write_RSAPrivateKey(fp, rsa, EVP_aes_256_cbc(), nullptr, 0, nullptr, &passW);
fclose(fp);

如果密码匹配,我希望使用相同的 RSA 密钥。

【问题讨论】:

  • 阅读BN_bn2bin 的文档,它从一个大数字(bn 由BN_new 初始化为0)转换并将其存储在提供的地址中(passW)。见:openssl.org/docs/man1.0.2/man3/BN_bn2bin.html
  • 在调用它之前你如何播种随机数生成器?
  • @SergeyA, RAND_seed(char rand_buff[16], 16);
  • 相同的种子可能导致相同的结果。试试看。保存你第一次得到的任何种子。如果密码被加盐,你也需要处理这个问题。
  • 您需要确保种子相同。如果种子相同,则输出将相同。

标签: c++ openssl


【解决方案1】:

阅读有关RAND_seed的文档我发现,我必须写一个rand engine (I took it from this answer),我已经针对我的问题修改了这个解决方案

// These don't need to do anything if you don't have anything for them to do.
static void stdlib_rand_cleanup() {}
static void stdlib_rand_add(const void *buf, int num, double add_entropy) {}
static int stdlib_rand_status() { return 1; }

// Seed the RNG. srand() takes an unsigned int, so we just use the first
// sizeof(unsigned int) bytes in the buffer to seed the RNG.
static void stdlib_rand_seed(const void *buf, int num)
{
    assert(num >= sizeof(unsigned int)); /// Use if statement, if u don't want to terminate ur app
    srand(*((unsigned int *)buf));
}

// Fill the buffer with random bytes.  For each byte in the buffer, we generate
// a random number and clamp it to the range of a byte, 0-255.
static int stdlib_rand_bytes(unsigned char *buf, int num)
{
    for(int index = 0; index < num; ++index)
    {
        buf[index] = rand() % 256;
    }
    return 1;
}

// Create the table that will link OpenSSL's rand API to our functions.
static RAND_METHOD stdlib_rand_meth = {
    stdlib_rand_seed,
    stdlib_rand_bytes,
    stdlib_rand_cleanup,
    stdlib_rand_add,
    stdlib_rand_bytes,
    stdlib_rand_status
};

// This is a public-scope accessor method for our table.
RAND_METHOD *RAND_stdlib() { return &stdlib_rand_meth; }

void createRSAKey() {
    // Intilize data
    int bits = 2048; // 512, 1024, 2048, 4096
    std::string passW = "password";    
    unsigned int randBuff = sizeof(passW);
    unsigned int randNum[4];

    // Create BIGNUM
    BIGNUM *bn = BN_new();
    BN_set_word(bn, RSA_3);

    // Create RSA
    RSA *rsa = RSA_new();

    // Connect algorithms, another way it crashes    
    OpenSSL_add_all_algorithms();

    // Randomize bytes
    RAND_set_rand_method(RAND_stdlib());
    RAND_seed(&randBuff, sizeof(randBuff));
    RAND_bytes(reinterpret_cast<unsigned char *>(&randNum[0]), sizeof(randNum));

    if(RSA_generate_key_ex(rsa, bits, bn, nullptr) != 1) { qDebug() << "error"; }

    // Save private key
    FILE *fp = fopen("private.key", "w");
    PEM_write_RSAPrivateKey(fp, rsa, nullptr, nullptr, 0, nullptr, &passW);
    fclose(fp);

    // Clear memory
    BN_free(bn);
    RSA_free(rsa);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 2012-09-29
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    相关资源
    最近更新 更多