尽管我仍然不确定这是否是“官方方式” /常用方式(适合写“这是钥匙的指纹”),但我在“ Deutsches Forschungsnetz”({{3 }}),他们使用密钥模数的哈希值。
可以使用BN_bn2hex(rsa.n)从PRSA获取十六进制表示形式的模数,并且必须以'Modulus ='为前缀并以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;