请教如何在delpih中使用HMAC-SHA1算法?
解决方案 »
- 如何获取某一个程序的启动参数?
- delphi 检测服务器上是否新版本和下载的几个问题
- delphi中,怎么做到像word在菜单里有打开文档的历史记录?我想用ini文件来记录,实现思路是什么?
- 如何控制路由器的断开,和链接
- 算是进阶的问题吧!在Delphi里,如何返回一个不同数据库源表的数据集?
- delphi 中的 quickreport 能否打印类似超市购物小票那样不限制长度的东西?
- 怎么在delphi的adoquery里判断一个数据库database是否存在?
- 请教各们高手关于字段长度的问题? 帮我解决后一定重谢。
- 谁现在能帮助我?
- 小女子的4至6问题
- 继续请教各位大神——Delphi7实现excel读取txt数据的问题~
- QQ 终结者
bs: TBytes;
begin
with TIdHMACSHA1.Create do
try
Key := ToBytes(HashKey);
bs := HashValue(ToBytes(BaseString));
finally
Free;
end;
end;
但delphi7下不支持HMac-Sha1算法。
怎么让delphi7下,可以调用Hmac-sha1算法,
没有可以直接调用的dll方式
最新是指xe4 版本吗?
/*
* 生成签名
* @param method HTTP请求方法 "get" / "post" //参数1:请求方式的字符串值
* @param url_path CGI名字, //参数2:api的相对URL的字符串值
* @param params URL请求参数 //参数3:由request的请求名和值,构成的hashmap数据类型值
* @param secret 密钥 //参数4:用户网站的appkey的字符串值
* @return 签名值 //返回值,对请求值进行hmac-sha1加密算法的计算返回值。
* @throws OpensnsException 不支持指定编码以及不支持指定的加密方法时抛出异常。
*/
private String makeSign(String method, String url_path, HashMap<String, String> params, String secret) throws OpenApiException {
String sig = "";
try {
Mac mac = Mac.getInstance("HmacSHA1"); //1 得到一个是hmacsha1的mac对象
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(charset), mac.getAlgorithm()); //2 创建secretKey对象
mac.init(secretKey); //3 用secretkey对象,初始化mac对象。
String mk = makeSource(method, url_path, params); //4 输入method、url_path,parms参数,得到源名码
System.out.println(mk);
byte[] hash = mac.doFinal(mk.getBytes(charset)); //5 用mac对源名码加密,得到byte数组
sig = new String(Base64Coder.encode(hash)); //6 encode编码,然后转化为string输出值
// sig = encodeUrl(sig);
} catch (Exception e) {
throw new OpenApiException(OpenApiException.MAKE_SIGNATURE_ERROR, e);
}
return sig;
}就是输入post/get 的string值、相对api的url string值、hashmap方式的request值、appkey的string值,经过hmac算法,得到计算的密码值。
zck(25594165) 18:04:19
源名码=源明码
这句就是核心,根据byte[]值,得到byte[]
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons,
IdHashMessageDigest, HTTPApp, IdHMACSHA1, IdCoderMIME, DateUtils;type
TForm3 = class(TForm)
BitBtn1: TBitBtn;
Memo1: TMemo;
procedure BitBtn1Click(Sender: TObject);
procedure Memo1Change(Sender: TObject); private
{ Private declarations }
function Base64Encode(const Input: TBytes): string;
function EncryptHMACSha1(Input,AKey:AnsiString): TBytes;
public
{ Public declarations }
end;var
Form3: TForm3;implementation{$R *.dfm}procedure TForm3.BitBtn1Click(Sender: TObject);var sHttpMethod: AnsiString; sRequestURL: AnsiString; sRequestParameter: AnsiString; sAppSecret: AnsiString; sSignatureBaseString: AnsiString; sMD5: TIdHashMessageDigest5;begin sMD5 := TIdHashMessageDigest5.Create; sAppSecret := '4b50186d12987f405b17bc38c9b99b0a&'; //密钥 sHttpMethod := 'GET'; sRequestURL := 'http://open.t.qq.com/cgi-bin/request_token'; sRequestParameter := 'oauth_callback=null&oauth_consumer_key=8*******9&oauth_nonce='; sRequestParameter := sRequestParameter + sMD5.HashStringAsHex(IntToStr(Random(10000)), nil); //随机32位数 sRequestParameter := sRequestParameter + '&oauth_signature_method=HMAC-SHA1&oauth_timestamp='; sRequestParameter := sRequestParameter + FloatToStr(DateTimeToUnix(Now()-1/3)); //时间戳 sRequestParameter := sRequestParameter + '&oauth_version=1.0'; sSignatureBaseString := HTTPEncode(sHttpMethod) + '&' + HTTPEncode(sRequestURL) + '&' + HTTPEncode(sRequestParameter); Memo1.Text := Base64Encode(EncryptHMACSha1(sSignatureBaseString, sAppSecret)); sMD5.Free;end;//两个函数 Base64Encode,EncryptHMACSha1;
//HMACSha1算法
function TForm3.EncryptHMACSha1(Input,AKey:AnsiString): TBytes;
var Key: TBytes;
begin with TIdHMACSHA1.Create do
try
Key := BytesOf(AKey);
Result := HashValue(BytesOf(Input)); finally
Free;
end;end;procedure TForm3.Memo1Change(Sender: TObject);
beginend;//Base64编码function TForm3.Base64Encode(const Input: TBytes): string;
begin Result := TIdEncoderMIME.EncodeBytes(Input);
end;
end.
// Base64编码
function Base64Encode(const Input: TIdBytes): string;
begin
Result := TIdEncoderMIME.EncodeBytes(Input);
end;// HMACSha1算法
function EncryptHMACSha1(Input, AKey: string): TIdBytes;
var
Key: TIdBytes;
begin
with TIdHMACSHA1.Create do
try
Key := TIdBytes(AKey);
Result := HashValue(TIdBytes(Input));
finally
Free;
end;
end;
然后delphi7去调用。
HMAC-SHA1的使用场合:
淘宝网api:MD5或HMAC-SHA1算法。
拍拍网api:HMAC-SHA1算法.
亚马逊api:HMAC-SHA256算法。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdHashMessageDigest, HTTPApp, IdHMACSHA1, IdCoderMIME, DateUtils,
StdCtrls, Types, IdGlobal, CnSHA1, EncdDecd, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdHTTP;type
TBytes = array of Byte;
TForm1 = class(TForm) btnOk: TButton;
Memo1: TMemo;
Label1: TLabel;
Label2: TLabel;
Memo2: TMemo;
IdHTTP1: TIdHTTP;
Memo3: TMemo;
Button1: TButton;
procedure btnOkClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
function EncryptHMACSha1(Input, AKey: AnsiString): TIdBytes;
function Base64Encode(const Input: TIdBytes): string;
//url编码
function URLEncode(const S: string; const InQueryString: Boolean): string;
function URLDecode(const S: string): string;
function HTMLEncode(const AStr: string): string;
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btnOkClick(Sender: TObject);
var
sHttpMethod: AnsiString;
sRequestURL: AnsiString;
sRequestParameter: AnsiString;
sAppSecret: AnsiString;
sSignatureBaseString: AnsiString;
sMD5: TIdHashMessageDigest5;
begin sMD5 := TIdHashMessageDigest5.Create;
//sAppSecret := '4b50186d12987f405b17bc38c9b99b0a&'; //密钥
sAppSecret := 'test';
sHttpMethod := 'Post'; sRequestURL := 'http://apis.youhuiin.com/api2'; sRequestParameter := 'nonce=';
sRequestParameter := sRequestParameter + IntToStr(Random(10000)); //随机32位数 sMD5.HashStringAsHex(IntToStr(Random(10000)), nil)
sRequestParameter := sRequestParameter + '&from=erp';
sRequestParameter := sRequestParameter + '&ts=';
sRequestParameter := sRequestParameter + FloatToStr(DateTimeToUnix(Now() - 1 / 3)); //时间戳
Memo2.Text := sRequestParameter;
// sRequestParameter := sRequestParameter + '&oauth_version=1.0';
// sSignatureBaseString := HTTPEncode(sHttpMethod) + '&' + HTTPEncode(sRequestURL) + '&' + HTTPEncode(sRequestParameter);
sSignatureBaseString := HTTPEncode(sHttpMethod) + '&' + HTTPEncode(sRequestURL) + '&' + HTTPEncode(sRequestParameter);
sSignatureBaseString :=HTTPEncode(sRequestParameter);
//sSignatureBaseString :='100&erp&12345678'; sSignatureBaseString:=HTTPEncode('nonce=100&from=erp&ts=12345678');
//indy10 Memo1.Text := URLEncode(Base64Encode(EncryptHMACSha1(sSignatureBaseString, sAppSecret)), true);
sMD5.Free; //添加CnSHA1.pas
// Memo1.Text :=URLEncode(EncodeString(CnSHA1.SHA1Print(CnSHA1.SHA1StringA(sSignatureBaseString))),false);
end;
//HMACSha1算法function TForm1.EncryptHMACSha1(Input, AKey: AnsiString): TIdBytes;
var
Key: TIdBytes;
begin
with TIdHMACSHA1.Create do
try
Key := ToBytes(AKey);
Result := HashValue(ToBytes(Input));
finally
Free;
end;
end;//Base64编码function TForm1.Base64Encode(const Input: TIdBytes): string;
begin
Result := TIdEncoderMIME.EncodeBytes(Input);
end;function TForm1.URLDecode(const S: string): string;
var
Idx: Integer; // loops thru chars in string
Hex: string; // string of hex characters
Code: Integer; // hex character code (-1 on error)
begin
// Intialise result and string index
Result := '';
Idx := 1;
// Loop thru string decoding each character
while Idx <= Length(S) do
begin
case S[Idx] of
'%':
begin
// % should be followed by two hex digits - exception otherwise
if Idx <= Length(S) - 2 then
begin
// there are sufficient digits - try to decode hex digits
Hex := S[Idx + 1] + S[Idx + 2];
Code := SysUtils.StrToIntDef('$' + Hex, -1);
Inc(Idx, 2);
end
else
// insufficient digits - error
Code := -1;
// check for error and raise exception if found
if Code = -1 then
raise SysUtils.EConvertError.Create(
'Invalid hex digit in URL'
);
// decoded OK - add character to result
Result := Result + Chr(Code);
end;
'+':
// + is decoded as a space
Result := Result + ' '
else
// All other characters pass thru unchanged
Result := Result + S[Idx];
end;
Inc(Idx);
end;
end;
function TForm1.URLEncode(const S: string; const InQueryString: Boolean): string;
var
Idx: Integer; // loops thru characters in string
begin
Result := '';
for Idx := 1 to Length(S) do
begin
case S[Idx] of
'A'..'Z', 'a'..'z', '0'..'9', '-', '_', '.':
Result := Result + S[Idx];
' ':
if InQueryString then
Result := Result + '+'
else
Result := Result + '%20';
else
Result := Result + '%' + SysUtils.IntToHex(Ord(S[Idx]), 2);
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
postcmd: TStringList;
sPostUrl: string;
begin
sPostUrl := 'http://apis.youhuiin.com/api2/order/prepareship?nonce=100&from=erp&ts=12345678&sign=LuW3%2f7AHkkA0WInXC73DDp85818%3d';
postcmd := TStringList.Create; // 组合参数列表
postcmd.Add('orderno=113092265023');
postcmd.Add('updatetime=2013-09-24 12:05:37');
postcmd.Add('memo=12333');
postcmd.Add('storeid=1');
IdHTTP1.Request.ContentType := 'application/json';
IdHTTP1.Request.AcceptCharSet:='gb2312';
Memo3.Text :=UTF8Decode(IdHTTP1.Post(sPostUrl, postcmd)); // 以post的方式发送到服务器
end;function TForm1.HTMLEncode(const AStr: string): string;
const
NoConversion = ['A'..'Z', 'a'..'z', '*', '.', '_', '-', '0'..'9', '!', '''', '(', ')']; //不需要进行转换的字符。
var
Sp, Rp: PChar;
begin
SetLength(Result, Length(AStr) * 3);
Sp := PChar(AStr);
Rp := PChar(Result);
while Sp^ <> #0 do
begin
if Sp^ in NoConversion then
Rp^ := Sp^
else
if Sp^ = ' ' then
Rp^ := '+'
else
begin
FormatBuf(Rp^, 3, '%%%.2x', 6, [Ord(Sp^)]);
Inc(Rp, 2);
end;
Inc(Rp);
Inc(Sp);
end;
SetLength(Result, Rp - PChar(Result));
end;
end.结果返回不对啊,和真实值不一样