Delphi XE 10.3.3 RSA 签名,IdSSLOpenSSLHeaders

unit Unit1;

interface

uses
  System.NetEncoding, IdGlobal, IdSSLOpenSSL, IdSSLOpenSSLHeaders, EncdDecd,
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function Sign(msg, keyfile: ansistring; zfj, jmfs: integer; var signstr: ansistring): integer;
  //zfj:字符集 0 utf8 1 gbk  jmfs:加密方式 0RSA 1RSA2 2MD5
var
//  Path: ansistring;
  pkey: PEVP_PKEY;
  bp: PBIO;
  md_ctx: EVP_MD_CTX;
  Buf: ansistring;
  len: integer;
  SigBuf: array[0..4095] of AnsiChar;
  SigLen: integer;
//  InBuf: array[0..1023] of AnsiChar;
begin
  result := -1;

  try
    if (not FileExists(keyfile)) then
    begin
      result := -2;
      exit;
    end;

    // 签名      sign_type=RSA2 或RSA
    Buf := Trim(msg);

    if zfj = 0 then // 如果用UTF-8请UTF8编码
      Buf := utf8encode(Buf);

    len := length(Buf);

    bp := BIO_new_file(PansiChar(keyfile), 'r'); // 加载私钥

    ShowMessage('加载私钥');

    try
      pkey := PEM_read_bio_PrivateKey(bp, nil, nil, nil);
    finally
      BIO_free(bp);
    end;

    case jmfs of
      0:
        EVP_SignInit(@md_ctx, EVP_sha1); // 如果用RSA用 EVP_sha1
      1:
        EVP_SignInit(@md_ctx, EVP_sha256); // 如果是RSA2用 EVP_sha256
      2:
        EVP_SignInit(@md_ctx, EVP_md5); // 如果用MD5用 EVP_md5
    end;

    EVP_SignUpdate(@md_ctx, PansiChar(Buf), len);

    EVP_SignFinal(@md_ctx, @SigBuf, @SigLen, pkey);

   // signstr := EncodeBase64(@SigBuf, SigLen);
    signstr := AnsiString(TNetEncoding.Base64.EncodeBytesToString(@SigBuf, SigLen));
    result := 0;
  except
    on E: Exception do
      result := -3;
  end;
end;

procedure TForm1.btn1Click(Sender: TObject);
var
  signstr: ansistring;
begin
  if Sign('123456', 'rsa_private_key.pem', 0, 0, signstr) = 0 then
  begin
    ShowMessage(signstr);

  end
  else
    ShowMessage('签名失败');
end;

end.