我有一个EVP_PKEY结构中的RSA公钥(从PEM文件加载,以------开始公钥------)。现在,我希望能够使用OpenSSL API显示代码中该密钥的指纹。(目的是允许操作员在信任JWT之前使用RS256验证其密钥)。
不幸的是,到目前为止,我发现的所有资源要么在命令行上使用ssh-keygen,要么使用X.509证书的指纹,但不使用公钥。
那么,如何使用OpenSSL API获取存储在EVP_PKEY结构中的公钥的RSA公钥指纹呢?
虽然我仍然不确定这是否是“官方方式”/一种常用的方式(适合写“这是钥匙的指纹”),但我在“Deutsches Forschungsnetz”(https://www.dfn-cert.de/informationen/themen/verschluesselung_und_pki/openssl-kurzreferenz.html)找到了一个参考,他们在那里使用钥匙的哈希模数。
十六进制表示中的模数可以通过BN_bn2hex(rsa.n)
从PRSA获取,并且必须以“模数=”作为前缀,并以CR/LF作为后缀,以产生与命令行相同的输出。这是我得到的Delphi代码:
function GetRsaModulusFingerprint(theRsa: PRSA; md: PEVP_MD; useLowerCase:
Boolean; const separator: string): string;
var
len: integer;
modulusStr: PAnsiChar;
buff: AnsiString;
mdValue: array [0..EVP_MAX_MD_SIZE-1] of Byte;
ctx: EVP_MD_CTX;
mdLen: Cardinal;
I: Integer;
begin
// This func should produce same result as commandline
// for public key:
// openssl rsa -noout -modulus -pubin -in server.pubkey |openssl sha256 -c
// for private key:
// openssl rsa -noout -modulus -in server.privkey |openssl sha256 -c
Result := '';
if not Assigned(theRsa) then
Exit;
// get hex representation of modulus
modulusStr := BN_bn2hex(theRsa.n);
// bring it in same format as commanline
buff := 'Modulus='+ AnsiString(modulusStr) + #13#10;
// and free the string returned by BN_bn2hex using OPENSSL_free
// (in openSSL1.0.2r crypto.h OPENSSL_free is a macro pointing to CRYPTO_free)
CRYPTO_free(modulusStr);
// calculate hash
len := length(buff);
if len >= 0 then
begin
EVP_MD_CTX_init(@ctx);
EVP_DigestInit_ex(@ctx, md, nil);
EVP_DigestUpdate(@ctx, PAnsiChar(buff), len);
EVP_DigestFinal_ex(@ctx, @mdValue[0], mdLen);
EVP_MD_CTX_cleanup(@ctx);
//output as hex with separator
result := '';
if mdLen > 0 then
result := IntToHex(mdValue[0]);
for I := 1 to mdLen-1 do
result := result + separator + IntToHex(mdValue[I]);
if useLowerCase then
result := result.ToLower();
end;
end;
在我自己的代码(C)中,我使用了以下代码,它接受一个EVP_PKEY对象并返回一个RSA对象:
using evp_pkey_ptr = std::unique_ptr<EVP_PKEY>;
using rsa_ptr = std::unique_ptr<RSA>;
rsa_ptr evp_get_rsa(const evp_pkey_ptr& evp) {
RSA * rsa = EVP_PKEY_get1_RSA(evp.get());
return rsa_ptr(rsa);
}
关于您验证JWT的目的。
我是这样做的:
// get jwt payload from jwt data
std::string payload_b64 = jwt[0] + "." + jwt[1];
// get jwt signature from jwt data
std::string signature_b64 = from_base64uri(jwt[2].c_str(), jwt[2].size());
// obtain RSA object from EVP
RSA * rsa = EVP_PKEY_get1_RSA(evp)
// create a digest of the jwt payload, using SHA256
digest = SHA256_Init, SHA256_Update, SHA256_Final, etc
// get byte representation of the jwt signature
sig_bytes = from_base64(payload_b64);
// call OpenSSL API to verify digest matches received signature
ERR_clear_error();
int rc = RSA_verify(NID_sha256,
(const unsigned char*) digest.data(), digest.size(),
(const unsigned char*) sig_bytes.data(), sig_bytes.size(),
rsa);
if (1 != rc)
printf("RSA_verify");
作为标题,如何在Java中从SSH RSA公钥计算指纹?我从sample.pub获得了一个rsaPublicKey对象,并使用库Apache Commons Codec但当使用ssh-keygen命令sample.pub时,我得到了不同的指纹,如下所示
主要的问题是,我对C相当陌生,OpenSSL留档对我来说不够清晰,我尝试过使用读和写rsa键到C中的pem文件,但我不太明白。例如,函数如何创建私有和公共?而从何而来?pcszPassphrase的意义是什么? 我会解释,好像这是某种伪代码,这就是我想做的,粗体部分是我不知道如何做的: 生成私钥和公钥作为十六进制缓冲区(客户端) 基本上,我知道如何处理AES加密/解密和通信协议,反正他们已经实现了
我知道可以使用此链接为OpenSSL中的自签名证书生成一个公钥和一个私钥。但是对于给定的公钥,我有没有可能算出对应的私钥呢?我一直在使用1024位的RSA公钥。
以下命令生成一个包含公钥和私钥的文件: 资料来源:这里 使用OpenSSL,私钥也包含公钥信息,因此公钥不需要单独生成 如何从私钥中提取公钥。pem文件? 谢谢
我想使用带有RSA算法的OpenSSL使用私钥加密文件: 现在,如果我执行解密操作: 此操作需要私钥 我知道我应该使用公钥进行加密,如果我使用私钥,我会得到一个签名。 然而,我想这样做是为了学习。
我需要从一个文件中提取公钥(RSA)。我希望提取密钥并将其存储在文件中,这样我就可以使用它的值来使用js加密加密值。 下面的命令转换至: 然而,它生成的不是带有公钥的文件,而是包含文件内容的文件。 我应该使用什么命令来提取公钥并将其存储在文件中?