unit CACase;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, IdHTTP, OleCtrls, SHDocVw, WebBrowserWithUI;
type
TCACaseFrm = class(TForm)
btn1: TButton;
btn2: TBitBtn;
btn3: TBitBtn;
btn4: TBitBtn;
wbrwsrwth1: TWebBrowserWithUI;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
procedure btn4Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
function Authenticate(AAuthURL, AAppSecret: PChar): PChar;
procedure OnRedirect(Sender: TObject; var dest: string;
var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
function DecodeClientKey(AOpenKey, AAppSecret, AClientKey: string): string;
function DecodeAdapter(AData, AKey: string): string;
{ Private declarations }
public
{ Public declarations }
end;
TAuthIdHTTP = class(TIdHTTP)
private
FAccessToken: string;
FClientKey: string;
public
property AccessToken: string read FAccessToken write FAccessToken;
property ClientKey: string read FClientKey write FClientKey;
end;
var
CACaseFrm: TCACaseFrm;
function Authenticate1(AAuthURL, AAppSecret: PChar): PChar; stdcall; external 'AppCentrelib.dll' Name 'Authenticate';
implementation
uses
CAImport, InterfaceCA, superobject, XXTEA, IdURI;
const
///
/// CA请求报文
///
REQUEST_STR: string =
'
' +
'1.0' +
'OriginalService' +
'' +
'' +
'%s' +
'';
///
/// 认证服务报文
///
AUTH_REQUEST_STR: string =
'' +
'1.0' +
'AuthenService' +
'' +
'' +
'' +
'%s' +
'' +
'%s' +
'' +
'' +
'%s' +
'%s' +
'' +
'' +
'false' +
'';
{$R *.dfm}
procedure TCACaseFrm.btn1Click(Sender: TObject);
begin
GetCAClient.Request;
end;
procedure TCACaseFrm.btn2Click(Sender: TObject);
begin
Authenticate(PCHar('http://oa.wswin.cn:8989/home/jump?appid=0B6AC133A3E1FC7F5A3109F8A81E0825&clientuin=31E65FD25C1D4D99A193CE5005B7813C&clientkey=CEABF7A66560F75F84347B3C2FE68BDC7B8B258942993F49&redirect_uri=&toappid=A0E0F1308C2111DF92D995795A3BCD40'),
PChar('B0F0E1308c2111EF92E995795A3DED42'));
end;
function StrToHex(Const str: Ansistring): Ansistring;
asm
push ebx
push esi
push edi
test eax,eax
jz @@Exit
mov esi,edx //保存edx值,用来产生新字符串的地址
mov edi,eax //保存原字符串
mov edx,[eax-4] //获得字符串长度
test edx,edx //检查长度
je @@Exit {Length(S) = 0}
mov ecx,edx //保存长度
Push ecx
shl edx,1
mov eax,esi
{$IFDEF VER210}
movzx ecx, word ptr [edi-12] {需要设置CodePage}
{$ENDIF}
call System.@LStrSetLength //设置新串长度
mov eax,esi //新字符串地址
Call UniqueString //产生一个唯一的新字符串,串位置在eax中
Pop ecx
@@SetHex:
xor edx,edx //清空edx
mov dl, [edi] //Str字符串字符
mov ebx,edx //保存当前的字符
shr edx,4 //右移4字节,得到高8位
mov dl,byte ptr[edx+@@HexChar] //转换成字符
mov [eax],dl //将字符串输入到新建串中存放
and ebx,$0F //获得低8位
mov dl,byte ptr[ebx+@@HexChar] //转换成字符
inc eax //移动一个字节,存放低位
mov [eax],dl
inc edi
inc eax
loop @@SetHex
@@Exit:
pop edi
pop esi
pop ebx
ret
@@HexChar: db '0123456789ABCDEF'
end;
function HexToStr(const Str: AnsiString): AnsiString;
asm
push ebx
push edi
push esi
test eax,eax //为空串
jz @@Exit
mov edi,eax
mov esi,edx
mov edx,[eax-4]
test edx,edx
je @@Exit
mov ecx,edx
push ecx
shr edx,1
mov eax,esi //开始构造字符串
{$IFDEF VER210}
movzx ecx, word ptr [edi-12] {需要设置CodePage}
{$ENDIF}
call System.@LStrSetLength //设置新串长度
mov eax,esi //新字符串地址
Call UniqueString //产生一个唯一的新字符串,串位置在eax中
Pop ecx
xor ebx,ebx
xor esi,esi
@@CharFromHex:
xor edx,edx
mov dl, [edi] //Str字符串字符
cmp dl, '0' //查看是否在0到f之间的字符
JB @@Exit //小于0,退出
cmp dl,'9' //小于=9
ja @@DoChar//CompOkNum
sub dl,'0'
jmp @@DoConvert
@@DoChar:
//先转成大写字符
and dl,$DF
cmp dl,'F'
ja @@Exit //大于F退出
add dl,10
sub dl,'A'
@@DoConvert: //转化
inc ebx
cmp ebx,2
je @@Num1
xor esi,esi
shl edx,4
mov esi,edx
jmp @@Num2
@@Num1:
add esi,edx
mov edx,esi
mov [eax],dl
xor ebx,ebx
inc eax
@@Num2:
dec ecx
inc edi
test ecx,ecx
jnz @@CharFromHex
@@Exit:
pop esi
pop edi
pop ebx
end;
procedure TCACaseFrm.btn3Click(Sender: TObject);
var
d, k, d1, k2: string;
begin
k := 'asdf';
d := '32324sdfas';
// d1 := Encrypt(d, k);
// ShowMessage(d1);
ShowMessage(DecryptNoHex(HexToStr(
'48BE536245C22280C1F1899C9C28D0E7646F267CA61C4DFBAD0107A7FF33E22A83A5D2394F8FD405C26FF401'),
'B0F0E1308c2111EF92E995795A3DED427AE31A14DEB647059A31073F1D641752'));
// ShowMessage(Decrypt(d1, k));
end;
procedure TCACaseFrm.btn4Click(Sender: TObject);
begin
Authenticate1(PChar('hellow'), PChar(111));
end;
function SplitString(const Source,Ch:string):TStringList;
var
Temp: string;
iLoop: Integer;
begin
Result := TStringList.Create;
Temp := Source;
iLoop := Pos(Ch, Source);
while iLoop <> 0 do
begin
Result.Add(copy(temp, 0, iLoop-1));
Delete(temp, 1, iLoop);
iLoop := Pos(Ch, Temp);
end;
Result.Add(temp);
end;
procedure TCACaseFrm.OnRedirect(Sender: TObject; var dest: string; var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
const
TOKEN: string = 'access_token=';
CLIENT_KEY: string = 'clientkey=';
var
AParamsStr: string;
AParams: TStrings;
iStart, iEnd, iCount, i: Integer;
begin
if NumRedirect = 3 then
begin
AParamsStr := dest;
AParams := SplitString(AParamsStr, '&');
try
for i := 0 to AParams.Count - 1 do
begin
iStart := Pos(TOKEN, AParams[i]);
if iStart > 0 then
begin
Inc(iStart, Length(TOKEN));
(Sender as TAuthIdHTTP).FAccessToken := Copy(AParams[i], iStart);
Break;
end;
end;
for i := 0 to AParams.Count - 1 do
begin
iStart := Pos(CLIENT_KEY, AParams[i]);
if iStart > 0 then
begin
Inc(iStart, Length(CLIENT_KEY));
(Sender as TAuthIdHTTP).FClientKey := Copy(AParams[i], iStart);
Break;
end;
end;
finally
AParams.Free;
end;
end;
end;
function TCACaseFrm.DecodeAdapter(AData, AKey: string): string;
const
TICKET_TAG: string = 'ticket=';
EXTEND_TAG: string = 'extend=';
ID_TAG: string = 'id=';
var
AResults: TStrings;
AResultStr, ATicket, AExtend, AID: string;
iStart, iEnd, iCount, i: Integer;
jo: ISuperObject;
begin
AResultStr := (Decrypt(AData, AKey));
if AResultStr = '' then
begin
ShowMessage('错误:解密失败.');
Exit;
end;
AResults := SplitString(AResultStr, '&');
try
for i := 0 to AResults.Count - 1 do
begin
iStart := Pos(TICKET_TAG, AResults[i]);
if iStart > 0 then
begin
Inc(iStart, Length(TICKET_TAG));
ATicket := Copy(AResults[i], iStart);
Break;
end;
end;
for i := 0 to AResults.Count - 1 do
begin
iStart := Pos(EXTEND_TAG, AResults[i]);
if iStart > 0 then
begin
Inc(iStart, Length(EXTEND_TAG));
AExtend := Copy(AResults[i], iStart);
Break;
end;
end;
for i := 0 to AResults.Count - 1 do
begin
iStart := Pos(ID_TAG, AResults[i]);
if iStart > 0 then
begin
Inc(iStart, Length(ID_TAG));
AID := Copy(AResults[i], iStart);
Break;
end;
end;
if (AID = '') or (ATicket = '') then
begin
ShowMessage('错误:解密失败,找不到关键信息.');
Exit;
end;
jo := SO('{}');
jo.I['ticket'] := StrToInt64(ATicket);
jo.S['id'] := AID;
jo.S['extend'] := AExtend;
Result := jo.AsJSon();
finally
AResults.Free;
end;
end;
function TCACaseFrm.Authenticate(AAuthURL, AAppSecret: PChar): PChar;
const
GET_OPENKEY: string = 'http://%s:%s/api/oauth/me?access_token=%s';
var
AIdHttp: TAuthIdHTTP;
AURL, AToken, AClientKey,
ASecret,
AOpenKey: string;
AHost: string;
joStr: string;
jo: ISuperObject;
AIDURL: TIdURI;
begin
AURL := string(AAuthURL);
ASecret := string(AAppSecret);
AIdHttp := TAuthIdHTTP.Create(nil);
AIDURL := TIdURI.Create(AURL);
try
AIdHttp.RedirectMaximum := 5;
AIdHttp.HandleRedirects := True;
AIdHttp.OnRedirect := OnRedirect;
AIdHttp.Get(AURL);
if (Length(AIdHttp.FAccessToken) = 0) or (Length(AIdHttp.FAccessToken) <> 32) then
begin
ShowMessage('错误:没有获取到通行证或不是有效的通行证,可能是因为认证链接已经过期.');
Exit;
end;
if (Length(AIdHttp.FClientKey) = 0) then
begin
ShowMessage('错误:您还没有绑定该应用的账号,请联系管理员绑定.');
Exit;
end;
AClientKey := AIdHttp.FClientKey;
AToken := AIdHttp.FAccessToken;
AURL := Format(GET_OPENKEY, [AIDURL.Host, AIDURL.Port, AToken]);
joStr := Utf8ToAnsi(AIdHttp.Get(AURL));
if joStr = '' then
begin
ShowMessage('错误:不能获取OpenKey.');
Exit;
end;
jo := SO(joStr);
if jo = nil then
begin
ShowMessage('错误:OpenKey格式错误.');
Exit;
end;
AOpenKey := jo.S['openkey'];
if AOpenKey = '' then
begin
ShowMessage('错误:OpenKey为null.');
Exit;
end;
try
Result := PChar(DecodeAdapter(AClientKey, (string(ASecret) + AOpenKey)));
except
on Ex: Exception do
begin
ShowMessage('错误:解密异常,' + Ex.Message + '.');
Result := nil;
end;
end;
finally
AIdHttp.Free;
AIDURL.Free;
end;
end;
function TCACaseFrm.DecodeClientKey(AOpenKey, AAppSecret, AClientKey: string): string;
begin
end;
procedure TCACaseFrm.FormCreate(Sender: TObject);
begin
wbrwsrwth1.Navigate(ExtractFilePath(paramstr(0)) + '111.html');
end;
end.