You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenSSL中CTR_DRBG实现确定性输出的技术问题咨询

解决OpenSSL EVP API调用CTR-DRBG的确定性输出问题

要让CTR-DRBG输出确定性结果,核心是让OpenSSL的CTR-DRBG进入测试模式,允许你传入固定的熵、Nonce等参数,而不依赖系统熵源。以下是针对你提供的测试向量的完整实现:

关键要点

  • 直接获取CTR-DRBG算法实例,通过提供者参数启用测试模式,而非使用TEST-RAND包装
  • 手动设置所有配置参数(派生函数、预测抵抗、自动重新播种)匹配测试向量要求
  • 用EVP_RAND_CTX_set_params传入固定的熵、Nonce和个性化字符串

完整代码实现

#include <openssl/evp.h>
#include <openssl/core_names.h>
#include <string.h>
#include <stdio.h>

// 十六进制字符串转字节数组
int hex2bin(const char *hex, unsigned char *bin, size_t bin_len) {
    size_t hex_len = strlen(hex);
    if (hex_len % 2 != 0 || bin_len < hex_len / 2)
        return 0;

    for (size_t i = 0; i < hex_len; i += 2) {
        sscanf(hex + i, "%2hhx", &bin[i / 2]);
    }
    return 1;
}

int main() {
    // 初始化OpenSSL(按需)
    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);

    // 测试向量参数
    const char *entropy_hex = "890eb067acf7382eff80b0c73bc872c6";
    const char *nonce_hex = "aad471ef3ef1d203";
    const char *expected_hex = "a5514ed7095f64f3d0d3a5760394ab42062f373a25072a6ea6bcfd8489e94af6cf18659fea22ed1ca0a9e33f718b115ee536b12809c31b72b08ddd8be1910fa3";
    const size_t output_len = 64; // 512 bits = 64 bytes

    // 转换为字节数组
    unsigned char entropy[16], nonce[8], expected[64], output[64];
    if (!hex2bin(entropy_hex, entropy, sizeof(entropy)) ||
        !hex2bin(nonce_hex, nonce, sizeof(nonce)) ||
        !hex2bin(expected_hex, expected, sizeof(expected))) {
        fprintf(stderr, "Hex to binary conversion failed\n");
        return 1;
    }

    // 获取测试模式下的CTR-DRBG(AES-128)
    OSSL_PROV_PARAM prov_params[] = {
        {OSSL_PROV_PARAM_TEST, "1"},
        {NULL, NULL}
    };
    EVP_RAND *rand = EVP_RAND_fetch(NULL, "CTR-DRBG:AES-128", prov_params);
    if (!rand) {
        fprintf(stderr, "Failed to fetch CTR-DRBG\n");
        return 1;
    }

    // 创建RAND上下文
    EVP_RAND_CTX *ctx = EVP_RAND_CTX_new(rand);
    EVP_RAND_free(rand);
    if (!ctx) {
        fprintf(stderr, "Failed to create RAND context\n");
        return 1;
    }

    // 设置CTR-DRBG配置参数:启用派生函数,关闭预测抵抗,关闭自动重新播种
    OSSL_PARAM params[] = {
        {OSSL_CTRDRBG_PARAM_DF, OSSL_PARAM_INTEGER, &(int){1}, sizeof(int), 0},
        {OSSL_CTRDRBG_PARAM_PREDICTION_RESISTANCE, OSSL_PARAM_INTEGER, &(int){0}, sizeof(int), 0},
        {OSSL_CTRDRBG_PARAM_RESEED_INTERVAL, OSSL_PARAM_INTEGER, &(unsigned long){0}, sizeof(unsigned long), 0},
        {NULL, 0, NULL, 0, 0}
    };
    if (!EVP_RAND_CTX_set_params(ctx, params)) {
        fprintf(stderr, "Failed to set DRBG config params\n");
        EVP_RAND_CTX_free(ctx);
        return 1;
    }

    // 设置测试熵、Nonce、个性化字符串(空)
    OSSL_PARAM test_params[] = {
        {OSSL_RAND_PARAM_TEST_ENTROPY, OSSL_PARAM_OCTET_STRING, entropy, sizeof(entropy), 0},
        {OSSL_RAND_PARAM_NONCE, OSSL_PARAM_OCTET_STRING, nonce, sizeof(nonce), 0},
        {OSSL_RAND_PARAM_PERSONALIZATION, OSSL_PARAM_OCTET_STRING, "", 0, 0},
        {NULL, 0, NULL, 0, 0}
    };
    if (!EVP_RAND_CTX_set_params(ctx, test_params)) {
        fprintf(stderr, "Failed to set test params\n");
        EVP_RAND_CTX_free(ctx);
        return 1;
    }

    // 实例化DRBG
    if (EVP_RAND_instantiate(ctx, 0, NULL, 0, NULL) <= 0) {
        fprintf(stderr, "Failed to instantiate DRBG\n");
        EVP_RAND_CTX_free(ctx);
        return 1;
    }

    // 生成随机数(无附加输入)
    if (EVP_RAND_generate(ctx, output, output_len, 0, NULL, 0) <= 0) {
        fprintf(stderr, "Failed to generate random bytes\n");
        EVP_RAND_CTX_free(ctx);
        return 1;
    }

    // 验证结果
    if (memcmp(output, expected, output_len) == 0) {
        printf("Success! Output matches expected result.\n");
    } else {
        printf("Error: Output does not match expected result.\n");
        printf("Expected: ");
        for (size_t i = 0; i < output_len; i++) printf("%02x", expected[i]);
        printf("\nGot:      ");
        for (size_t i = 0; i < output_len; i++) printf("%02x", output[i]);
        printf("\n");
    }

    // 清理资源
    EVP_RAND_CTX_free(ctx);
    return 0;
}

代码说明

  1. 测试模式启用:通过OSSL_PROV_PARAM_TEST参数让CTR-DRBG进入测试模式,允许传入自定义熵而非依赖系统熵源
  2. 配置参数匹配:
    • OSSL_CTRDRBG_PARAM_DF=1:启用派生函数,匹配测试向量要求
    • OSSL_CTRDRBG_PARAM_PREDICTION_RESISTANCE=0:关闭预测抵抗
    • OSSL_CTRDRBG_PARAM_RESEED_INTERVAL=0:禁用自动重新播种
  3. 参数传入:通过OSSL_RAND_PARAM_TEST_ENTROPY、OSSL_RAND_PARAM_NONCE传入固定值,个性化字符串设为空
  4. 结果验证:对比生成的字节数组与测试向量的预期值

编译时需链接OpenSSL库:

gcc -o ctr_drbg_test ctr_drbg_test.c -lcrypto

内容的提问来源于stack exchange,提问作者Francisco Abelardo Garcia Avil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 04:32:14