9

我需要为 Amazon Web 服务 API 生成 HMAC-SHA256 签名。旧的 DCPcrypt 库具有 sha256 例程,但不进行 HMAC 签名。有人知道我可以使用的免费哈希库吗?

4

9 回答 9

7

Delphi 安装了 Indy,Indy 有一个TIdHMACSHA256类:

uses
  IdGlobal, IdHashSHA, IdHMAC, IdHMACSHA1, IdSSLOpenSSL;

function CalculateHMACSHA256(const value, salt: String): String;
var
  hmac: TIdHMACSHA256;
  hash: TIdBytes;
begin
  LoadOpenSSLLibrary;
  if not TIdHashSHA256.IsAvailable then
    raise Exception.Create('SHA256 hashing is not available!');
  hmac := TIdHMACSHA256.Create;
  try
    hmac.Key := IndyTextEncoding_UTF8.GetBytes(salt);
    hash := hmac.HashValue(IndyTextEncoding_UTF8.GetBytes(value));
    Result := ToHex(hash);
  finally
    hmac.Free;
  end;
end;
于 2016-10-21T17:43:24.617 回答
4

经过一番搜索后,我找到了 OpenStreamSec - 看起来它在几年前就被废弃了,但仍在 D2007 中编译。

http://sourceforge.net/projects/openstrsecii/

为 Amazon 生成 HMAC-256 非常简单:

StrToMime64(HMACString(haSHA256, SecretKey, 32, DataToHash));
于 2010-01-05T21:23:12.933 回答
3

我最喜欢的答案 - 我会使用 OpenSSL 库、HMAC 函数。通过采用和改编 M Ferrante http://www.disi.unige.it/person/FerranteM/delphiopenssl/
的工作,我已经成功地在 Delphi 中使用了 OpenSSL 库。 对于其他 OpenSSL 签名等,请参阅此链接
在 D2010 中是这样的(libeay32 是取自网站的单位,针对 unicode/D2010 稍作修改):

uses libeay32;

const
  LIBEAY_DLL_NAME = 'libeay32.dll';
  EVP_MAX_MD_SIZE = 64;

function EVP_sha256: pEVP_MD; cdecl; external LIBEAY_DLL_NAME;
function HMAC(evp: pEVP_MD; key: PByte; key_len: integer; 
              data: PByte; data_len: integer; 
              md: PByte; var md_len: integer): PByte; cdecl; external LIBEAY_DLL_NAME;

function GetHMAC(const AKey, AData: string): TBytes;
var
  key, data: TBytes;
  md_len: integer;
  res: PByte;
begin
  OpenSSL_add_all_algorithms;
  // Seed the pseudo-random number generator
  // This should be something a little more "random"!
  RAND_load_file('c:\windows\paint.exe', 512);

  key := TEncoding.UTF8.GetBytes(AKey);
  data := TEncoding.UTF8.GetBytes(AData);
  md_len := EVP_MAX_MD_SIZE;
  SetLength(result, md_len);
  res := HMAC(EVP_sha256, @key[0], Length(key), @data[0], Length(data), @result[0], md_len);
  if (res <> nil) then
  begin
    SetLength(result, md_len);
  end;
end;

然后用关键短语和数据字符串调用它。结果是一个 TBytes,可以根据需要转换为 Base64,例如使用 JclMime 或简单的 HexToString 类型函数。
对于旧版本的 Delphi,您必须将 PBytes 更改为 PChars 或类似的东西。
免责声明:我没有参考数据来测试它,但它似乎工作正常!

于 2010-01-05T12:26:50.430 回答
2

你看过这个SO问题的答案吗?

于 2010-01-05T00:32:02.733 回答
2

HMAC 只是一个使用 SHA256 根据一些定义的规则计算哈希的函数。如果您查看Wikipedia,它有一个伪代码示例。

您还可以通过 COM 互操作调用 System.Security.Cryptography 中的 .NET 的HMAC 类。

于 2010-01-05T03:53:09.973 回答
0

关于 Jacob 的回答:OpenStrSecII 是 StreamSec Tools 2.1 的一个分支,它是在商业严肃许可下出售的,今天(2012 年 2 月 8 日)支持 Delphi Win32,包括 Delphi XE2。StreamSec Tools 4.0 也支持 Win64。

于 2012-02-08T10:02:53.797 回答
0

在网上搜索时我也发现了这个,在Delphi10下编译正确:

result:= (TNetEncoding.Base64.EncodeBytesToString(THashSHA2.GetHMACAsBytes(TEncoding.UTF8.GetBytes(StringToSign),TNetEncoding.Base64.DecodeStringToBytes(Key))));

尽管我在正在进行的过程中确实遇到了麻烦-不确定它是否与此功能有关..

于 2020-04-28T10:32:47.850 回答
0

GetHMAC函数在类中也可用THashSHA2,在模块中System.Hash

我不确定这是从哪个版本的 Delphi 中可用的。它肯定在 Delphi 10 Seattle 及以后。

于 2021-03-25T21:42:57.000 回答
0

使用最新版本的 Delphi,一切都变得简单多了……

uses system.hash;
 
var s, sst:string;
bt:TBytes;

HMAC 256:

s:=THashSHA2.GetHMAC(DATA, KEY, SHA256);

base64 HMAC 256:

bt:= THashSHA2.GetHMACAsBytes(DATA, KEY, SHA256);
sst:= TNetEncoding.Base64.EncodeBytesToString(bt);
于 2022-01-14T20:40:54.860 回答