openssl3.2 - 官方demo学习 - kdf - argon2.c

文章目录

    • [openssl3.2 - 官方demo学习 - kdf - argon2.c](#openssl3.2 - 官方demo学习 - kdf - argon2.c)
    • 概述
    • 笔记
    • END

openssl3.2 - 官方demo学习 - kdf - argon2.c

概述

设置KDF算法的参数, 并获得key

笔记

c 复制代码
/*!
\file argon2.c
\note openssl3.2 - 官方demo学习 - kdf - argon2.c
设置KDF算法的参数, 并获得key
*/

/*
 * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdio.h>
#include <openssl/core_names.h>
#include <openssl/crypto.h>
#include <openssl/kdf.h>
#include <openssl/params.h>
#include <openssl/thread.h>

#include "my_openSSL_lib.h"

/*
 * Example showing how to use Argon2 KDF.
 * See man EVP_KDF-ARGON2 for more information.
 *
 * test vector from
 * https://datatracker.ietf.org/doc/html/rfc9106
 */

/*
 * Hard coding a password into an application is very bad.
 * It is done here solely for educational purposes.
 */
static unsigned char password[] = {
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};

/*
 * The salt is better not being hard coded too.  Each password should have a
 * different salt if possible.  The salt is not considered secret information
 * and is safe to store with an encrypted password.
 */
static unsigned char salt[] = {
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
};

/*
 * Optional secret for KDF
 */
static unsigned char secret[] = {
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
};

/*
 * Optional additional data
 */
static unsigned char ad[] = {
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04
};

/*
 * Argon2 cost parameters
 */
static uint32_t memory_cost    = 32;
static uint32_t iteration_cost =  3;
static uint32_t parallel_cost  =  4;

static const unsigned char expected_output[] = {
   0x0d, 0x64, 0x0d, 0xf5, 0x8d, 0x78, 0x76, 0x6c,
   0x08, 0xc0, 0x37, 0xa3, 0x4a, 0x8b, 0x53, 0xc9,
   0xd0, 0x1e, 0xf0, 0x45, 0x2d, 0x75, 0xb6, 0x5e,
   0xb5, 0x25, 0x20, 0xe9, 0x6b, 0x01, 0xe6, 0x59
};

int main(int argc, char **argv)
{
    int rv = EXIT_FAILURE;
    EVP_KDF *_evp_kdf = NULL;
    EVP_KDF_CTX *_evp_kdf_ctx = NULL;
    unsigned char out[32];
    OSSL_PARAM _ossl_param_ary[9], *p_ossl_param = _ossl_param_ary;
    OSSL_LIB_CTX *_ossl_lib_ctx = NULL;
    unsigned int threads;

    _ossl_lib_ctx = OSSL_LIB_CTX_new();
    if (_ossl_lib_ctx == NULL) {
        fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");
        goto end;
    }

    /* Fetch the key derivation function implementation */
    _evp_kdf = EVP_KDF_fetch(_ossl_lib_ctx, "argon2id", NULL);
    if (_evp_kdf == NULL) {
        fprintf(stderr, "EVP_KDF_fetch() returned NULL\n");
        goto end;
    }

    /* Create a context for the key derivation operation */
    _evp_kdf_ctx = EVP_KDF_CTX_new(_evp_kdf);
    if (_evp_kdf_ctx == NULL) {
        fprintf(stderr, "EVP_KDF_CTX_new() returned NULL\n");
        goto end;
    }

    /*
     * Thread support can be turned off; use serialization if we cannot
     * set requested number of threads.
     */
    threads = parallel_cost;
    if (OSSL_set_max_threads(_ossl_lib_ctx, parallel_cost) != 1) {
        uint64_t max_threads = OSSL_get_max_threads(_ossl_lib_ctx);

        if (max_threads == 0)
            threads = 1;
        else if (max_threads < parallel_cost)
            threads = (unsigned int)max_threads;
    }

    /* Set password */
    *p_ossl_param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, password, sizeof(password));
    /* Set salt */
    *p_ossl_param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, salt, sizeof(salt));
    /* Set optional additional data */
    *p_ossl_param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_ARGON2_AD, ad, sizeof(ad));
    /* Set optional secret */
    *p_ossl_param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, secret, sizeof(secret));
    /* Set iteration count */
    *p_ossl_param++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ITER, &iteration_cost);
    /* Set threads performing derivation (can be decreased) */
    *p_ossl_param++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_THREADS, &threads);
    /* Set parallel cost */
    *p_ossl_param++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_LANES, &parallel_cost);
    /* Set memory requirement */
    *p_ossl_param++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST, &memory_cost);
    *p_ossl_param = OSSL_PARAM_construct_end();

    /* Derive the key */
    if (EVP_KDF_derive(_evp_kdf_ctx, out, sizeof(out), _ossl_param_ary) != 1) {
        fprintf(stderr, "EVP_KDF_derive() failed\n");
        goto end;
    }

    if (CRYPTO_memcmp(expected_output, out, sizeof(expected_output)) != 0) {
        fprintf(stderr, "Generated key does not match expected value\n");
        goto end;
    }

    rv = EXIT_SUCCESS;
end:
    EVP_KDF_CTX_free(_evp_kdf_ctx);
    EVP_KDF_free(_evp_kdf);
    OSSL_LIB_CTX_free(_ossl_lib_ctx);
    return rv;
}

END

相关推荐
coder4_3 天前
OpenSSL 加密算法与证书管理全解析:从基础到私有 CA 实战
https·openssl·ssl/tls·加密算法·ca证书
王小义笔记10 天前
windows电脑如何执行openssl rand命令
windows·openssl
Humbunklung13 天前
VC++ 使用OpenSSL创建RSA密钥PEM文件
开发语言·c++·openssl
深耕AI1 个月前
Win64OpenSSL-3_5_2.exe【安装步骤】
openssl
看那山瞧那水1 个月前
DELPHI 利用OpenSSL实现加解密,证书(X.509)等功能
delphi·openssl
洋哥网络科技2 个月前
openssl升级
openssl
Lazy Dave2 个月前
gmssl私钥文件格式
网络安全·ssl·openssl
沉在嵌入式的鱼3 个月前
RK3588移植Openssl库
linux·rk3588·openssl
黑屋里的马3 个月前
ssl相关命令生成证书
服务器·网络·ssl·openssl·gmssl
fangeqin3 个月前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl