如何使用 OpenSSL libcrypto 生成 DSA 密钥对?
How to generate a DSA key pair using OpenSSL libcrypto?
我有以下代码试图生成 DSA 密钥对。
OpenSSL_add_all_algorithms();
ctx=EVP_PKEY_CTX_new_id(EVP_PKEY_DSA,NULL); EVP_PKEY_keygen_init(ctx);
if (EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx,1024)<=0) ERR_print_errors_fp(stderr);
我收到以下错误
3073906944:error:06089094:digital envelope
routines:EVP_PKEY_CTX_ctrl:invalid operation:pmeth_lib.c:398:
关于我做错了什么的任何线索?谢谢
您需要两个上下文;一个用于参数,一个用于实际的注册机。您应该执行以下 两 组操作:
参数生成
- 使用
EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL)
创建参数生成器
- 使用
EVP_PKEY_CTX_set_dsa_paramgen_bits
设置参数生成器上下文中的位; 不是 注册机上下文(如果你做对了,它甚至还不存在)。
- 使用
EVP_PKEY_paramgen_init
初始化参数生成器
- 最后,使用
EVP_PKEY_paramgen
生成参数。结果是一个 EVP_PKEY
对象(我将其称为 pkey_params
),其中包含即将生成密钥的输入参数
完成上述操作后,然后您将继续进行实际的密钥生成,这要简单得多:
密钥生成
- 使用
EVP_PKEY_CTX_new(pkey_params, NULL)
创建新上下文请注意 pkey_params
来自前面的一系列步骤。
- 使用
EVP_PKEY_keygen_init
初始化生成器上下文
- 使用
EVP_PKEY_keygen
生成实际密钥
完成后,除了上面最后的 pkey
之外的所有资源都应该被妥善销毁。使用完成后释放最终密钥。就是这样。
例子
这没有任何错误检查,但操作顺序在这里很重要。所以要注意这一点。
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/dsa.h>
#include <openssl/pem.h>
// required for any BIO standard stream IO.
#include <openssl/applink.c>
int main()
{
OPENSSL_init();
OpenSSL_add_all_algorithms();
// build parameters first
EVP_PKEY_CTX *ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
EVP_PKEY_paramgen_init(ctx_params);
EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params, 1024);
EVP_PKEY* pkey_params = NULL;
EVP_PKEY_paramgen(ctx_params, &pkey_params);
// using parameters, build DSA keypair
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey_params, NULL);
EVP_PKEY_keygen_init(ctx);
EVP_PKEY* pkey = NULL;
EVP_PKEY_keygen(ctx, &pkey);
// cleanup everything but the final key
EVP_PKEY_free(pkey_params);
EVP_PKEY_CTX_free(ctx_params);
EVP_PKEY_CTX_free(ctx);
// TODO: whatever you want with the generator pkey. in this
// example we're just dumping the full unencrypted key to
// stdout.
DSA* dsa = EVP_PKEY_get1_DSA(pkey);
BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE);
PEM_write_bio_DSAPrivateKey(bio, dsa, NULL, NULL, 0, NULL, NULL);
BIO_flush(bio);
DSA_free(dsa);
EVP_PKEY_free(pkey);
return 0;
}
输出(明显不同)
-----BEGIN DSA PRIVATE KEY-----
MIIBuwIBAAKBgQDJ+NoL8SZeTcqVA83WI7CCO6INYLw18DiALLMewPqXEPm99mof
RX2693WJfpbWIjuHi/KXzH6vQ/0sQU+2z1CqgWhudVhQTofGNcsPrUbPpShTDMcP
OoTx9dRb8rXWbxg7dfhGZ9z2pEhzRtPWpI2y81VxYhGXzVSC3zqW6+ec2QIVALaE
fynSMqc56gPqDPZfRz1rlq3dAoGAL+vbbYu+gSy8zGqoLykqhG+Vl4/Eh/zQIWoB
t64bfh7GU6o0wvgTQgcdGZK3/laa9Msa6J3iEGZcP3dd9x4fTQ5vzxDGIYikcC8I
L8s2JbNi1Jxbr5dw3/sOKsdHIt95rFZ03+gMzaV+9pc8LpATnaXMtp5mmH+lRgsJ
SIEdLqcCgYAVGpwZHaFUnttqQAf3/ohMtqIQG+RBp/yUf2EA7rcoHpA7bCBADApx
mG5hH/F4dKjCSciKdHq4Ibf60ctAJNL2sobPKNArTMo/GNuzE+J79Wj6s/b7zwt7
AF+27H9PAiXB08ftMmCSesXkX7v926EHRxDgSlVAgCPSfkXKNQn1XwIVALF2MF2N
GRdMtFUxZFnIk2GnqC1R
-----END DSA PRIVATE KEY-----
我有以下代码试图生成 DSA 密钥对。
OpenSSL_add_all_algorithms();
ctx=EVP_PKEY_CTX_new_id(EVP_PKEY_DSA,NULL); EVP_PKEY_keygen_init(ctx);
if (EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx,1024)<=0) ERR_print_errors_fp(stderr);
我收到以下错误
3073906944:error:06089094:digital envelope routines:EVP_PKEY_CTX_ctrl:invalid operation:pmeth_lib.c:398:
关于我做错了什么的任何线索?谢谢
您需要两个上下文;一个用于参数,一个用于实际的注册机。您应该执行以下 两 组操作:
参数生成
- 使用
EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL)
创建参数生成器
- 使用
EVP_PKEY_CTX_set_dsa_paramgen_bits
设置参数生成器上下文中的位; 不是 注册机上下文(如果你做对了,它甚至还不存在)。 - 使用
EVP_PKEY_paramgen_init
初始化参数生成器
- 最后,使用
EVP_PKEY_paramgen
生成参数。结果是一个EVP_PKEY
对象(我将其称为pkey_params
),其中包含即将生成密钥的输入参数
完成上述操作后,然后您将继续进行实际的密钥生成,这要简单得多:
密钥生成
- 使用
EVP_PKEY_CTX_new(pkey_params, NULL)
创建新上下文请注意pkey_params
来自前面的一系列步骤。 - 使用
EVP_PKEY_keygen_init
初始化生成器上下文
- 使用
EVP_PKEY_keygen
生成实际密钥
完成后,除了上面最后的 pkey
之外的所有资源都应该被妥善销毁。使用完成后释放最终密钥。就是这样。
例子
这没有任何错误检查,但操作顺序在这里很重要。所以要注意这一点。
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/dsa.h>
#include <openssl/pem.h>
// required for any BIO standard stream IO.
#include <openssl/applink.c>
int main()
{
OPENSSL_init();
OpenSSL_add_all_algorithms();
// build parameters first
EVP_PKEY_CTX *ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
EVP_PKEY_paramgen_init(ctx_params);
EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params, 1024);
EVP_PKEY* pkey_params = NULL;
EVP_PKEY_paramgen(ctx_params, &pkey_params);
// using parameters, build DSA keypair
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey_params, NULL);
EVP_PKEY_keygen_init(ctx);
EVP_PKEY* pkey = NULL;
EVP_PKEY_keygen(ctx, &pkey);
// cleanup everything but the final key
EVP_PKEY_free(pkey_params);
EVP_PKEY_CTX_free(ctx_params);
EVP_PKEY_CTX_free(ctx);
// TODO: whatever you want with the generator pkey. in this
// example we're just dumping the full unencrypted key to
// stdout.
DSA* dsa = EVP_PKEY_get1_DSA(pkey);
BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE);
PEM_write_bio_DSAPrivateKey(bio, dsa, NULL, NULL, 0, NULL, NULL);
BIO_flush(bio);
DSA_free(dsa);
EVP_PKEY_free(pkey);
return 0;
}
输出(明显不同)
-----BEGIN DSA PRIVATE KEY-----
MIIBuwIBAAKBgQDJ+NoL8SZeTcqVA83WI7CCO6INYLw18DiALLMewPqXEPm99mof
RX2693WJfpbWIjuHi/KXzH6vQ/0sQU+2z1CqgWhudVhQTofGNcsPrUbPpShTDMcP
OoTx9dRb8rXWbxg7dfhGZ9z2pEhzRtPWpI2y81VxYhGXzVSC3zqW6+ec2QIVALaE
fynSMqc56gPqDPZfRz1rlq3dAoGAL+vbbYu+gSy8zGqoLykqhG+Vl4/Eh/zQIWoB
t64bfh7GU6o0wvgTQgcdGZK3/laa9Msa6J3iEGZcP3dd9x4fTQ5vzxDGIYikcC8I
L8s2JbNi1Jxbr5dw3/sOKsdHIt95rFZ03+gMzaV+9pc8LpATnaXMtp5mmH+lRgsJ
SIEdLqcCgYAVGpwZHaFUnttqQAf3/ohMtqIQG+RBp/yUf2EA7rcoHpA7bCBADApx
mG5hH/F4dKjCSciKdHq4Ibf60ctAJNL2sobPKNArTMo/GNuzE+J79Wj6s/b7zwt7
AF+27H9PAiXB08ftMmCSesXkX7v926EHRxDgSlVAgCPSfkXKNQn1XwIVALF2MF2N
GRdMtFUxZFnIk2GnqC1R
-----END DSA PRIVATE KEY-----