我有一个用于OpenSSL的命令行:
openssl pkeyutl -inkey private.key -sign -in b64.dat -pkeyopt digest:SHA256 -out result.dat
我想使用C ++和OpenSSL库进行编码。
对于CURL,有一条诸如--libcurl code.c
之类的指令,它以给定命令的C语言输出等效代码,这可以节省大量时间。
OpenSSL中是否存在这种情况?如果没有,该命令等效于什么?
答案 0 :(得分:0)
为了对已经散列的字符串进行签名,我们可以使用EVP_PKEY_sign
;
此处的私钥必须是带有PEM格式的解密私钥的字符串。
将结果写入文件result.dat中,我们可以base64 result.dat
(在Linux中)获得有效的签名。
RSA* createPrivateRSA(std::string key) {
RSA *rsa = NULL;
const char* c_string = key.c_str();
BIO * keybio = BIO_new_mem_buf((void*)c_string, -1);
if (keybio==NULL) {
return 0;
}
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
return rsa;
}
void sellar(std::string hashclear, std::string privateKey_string){
EVP_PKEY_CTX *ctx;
/* md is a SHA-256 digest in this example. */
unsigned char *sig;
size_t siglen;
unsigned char clear_message[hashclear.length()];
strcpy((char*) clear_message,hashclear.c_str());
size_t mdlen;
// //1. Decodificar hashclear. || base64 -d data.dat > b64.dat -> Me debe dar una cadena de 32 bytes.
unsigned char * md = base64_decode(clear_message, strlen((char*) clear_message), &mdlen);
std::cout << "MD is " << mdlen << " bytes long.\n";
// //2. Cargar llave privada.
RSA* privateRSA = createPrivateRSA(privateKey);
EVP_PKEY* signing_key = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signing_key, privateRSA);
ctx = EVP_PKEY_CTX_new(signing_key, NULL /* no engine */);
if(!ctx) {
std::cout << "Error CTX_new" << std::endl;
return;
}
if (EVP_PKEY_sign_init(ctx) <= 0){
std::cout << "Error sign_init\n";
return;
}
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0){
std::cout << "Error set_rsa_padding\n";
return;
}
if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0){
std::cout << "Error set_signature_md\n";
return;
}
/* Determine buffer length */
if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0){
std::cout << "Error PKEY_sign\n";
return;
}
sig = (unsigned char*)OPENSSL_malloc(siglen);
if (!sig){
std::cout << "Error malloc";
return;
}
if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0){
std::cout << "Error sign";
return;
}
std::cout << siglen << " bytes written in buffer sig\n";
/* Signature is siglen bytes written to buffer sig */
size_t cadena_sellada_len;
unsigned char * cadena_sellada = base64_encode(sig, siglen, &cadena_sellada_len);
std::ofstream myfile ("result_final.dat");
if (myfile.is_open())
{
for(int count = 0; count < cadena_sellada_len; count ++){
myfile << cadena_sellada[count] ;
}
myfile.close();
}
else std::cout << "Unable to open file";
}
答案 1 :(得分:-2)
OpenSSL中是否存在这种情况?
是的,像openssl本身一样使用libssl和libcrypto(具有特定于平台的名称)-但据我了解,如果愿意,最好使用this这样的c ++准备的库正确地做。
如果没有,那么此命令等效于什么?
也是-如果我对您没错,您正在搜索类似的内容
#include <iostream>
int main ()
{
system("openssl pkeyutl -inkey private.key -sign -in b64.dat -pkeyopt digest:SHA256 -out result.dat"); //in one line
return 0;
}
“系统”在从其开始的终端中将c ++字符串转换为bash代码,并且效果很好。
希望对您有所帮助:)如果您需要第一个示例的进一步帮助,我可以编辑我的帖子-请就您的需要发表评论。
此外,如果您获得了正确的答案,请避免将您的问题检查为已解决,以避免它出现在stackoverflow.com的“未解决”部分;)