CACase.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. unit CACase;
  2. interface
  3. uses
  4. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5. Dialogs, StdCtrls, Buttons, IdHTTP, OleCtrls, SHDocVw, WebBrowserWithUI;
  6. type
  7. TCACaseFrm = class(TForm)
  8. btn1: TButton;
  9. btn2: TBitBtn;
  10. btn3: TBitBtn;
  11. btn4: TBitBtn;
  12. wbrwsrwth1: TWebBrowserWithUI;
  13. procedure btn1Click(Sender: TObject);
  14. procedure btn2Click(Sender: TObject);
  15. procedure btn3Click(Sender: TObject);
  16. procedure btn4Click(Sender: TObject);
  17. procedure FormCreate(Sender: TObject);
  18. private
  19. function Authenticate(AAuthURL, AAppSecret: PChar): PChar;
  20. procedure OnRedirect(Sender: TObject; var dest: string;
  21. var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
  22. function DecodeClientKey(AOpenKey, AAppSecret, AClientKey: string): string;
  23. function DecodeAdapter(AData, AKey: string): string;
  24. { Private declarations }
  25. public
  26. { Public declarations }
  27. end;
  28. TAuthIdHTTP = class(TIdHTTP)
  29. private
  30. FAccessToken: string;
  31. FClientKey: string;
  32. public
  33. property AccessToken: string read FAccessToken write FAccessToken;
  34. property ClientKey: string read FClientKey write FClientKey;
  35. end;
  36. var
  37. CACaseFrm: TCACaseFrm;
  38. function Authenticate1(AAuthURL, AAppSecret: PChar): PChar; stdcall; external 'AppCentrelib.dll' Name 'Authenticate';
  39. implementation
  40. uses
  41. CAImport, InterfaceCA, superobject, XXTEA, IdURI;
  42. const
  43. /// <remarks>
  44. /// CA请求报文
  45. /// </remarks>
  46. REQUEST_STR: string =
  47. '<head>' +
  48. '<version>1.0</version>' +
  49. '<servicetype>OriginalService</servicetype>' +
  50. '</head>' +
  51. '<body>' +
  52. '<appid>%s</appid>' +
  53. '</body>';
  54. /// <remarks>
  55. /// 认证服务报文
  56. /// </remarks>
  57. AUTH_REQUEST_STR: string =
  58. '<head>' +
  59. '<version>1.0</version>' +
  60. '<servicetype>AuthenService</servicetype>' +
  61. '</head>' +
  62. '<body>' +
  63. '<clientInfo>' +
  64. '<clientIP>%s</clientIP>' +
  65. '</clientInfo>' +
  66. '<appId>%s</appId>' +
  67. '<authen>' +
  68. '<authCredential authMode="cert">' +
  69. '<detach>%s</detach>' +
  70. '<original>%s</original>' +
  71. '</authCredential>' +
  72. '</authen>' +
  73. '<accessControl>false</accessControl>' +
  74. '</body>';
  75. {$R *.dfm}
  76. procedure TCACaseFrm.btn1Click(Sender: TObject);
  77. begin
  78. GetCAClient.Request;
  79. end;
  80. procedure TCACaseFrm.btn2Click(Sender: TObject);
  81. begin
  82. Authenticate(PCHar('http://oa.wswin.cn:8989/home/jump?appid=0B6AC133A3E1FC7F5A3109F8A81E0825&clientuin=31E65FD25C1D4D99A193CE5005B7813C&clientkey=CEABF7A66560F75F84347B3C2FE68BDC7B8B258942993F49&redirect_uri=&toappid=A0E0F1308C2111DF92D995795A3BCD40'),
  83. PChar('B0F0E1308c2111EF92E995795A3DED42'));
  84. end;
  85. function StrToHex(Const str: Ansistring): Ansistring;
  86. asm
  87. push ebx
  88. push esi
  89. push edi
  90. test eax,eax
  91. jz @@Exit
  92. mov esi,edx //保存edx值,用来产生新字符串的地址
  93. mov edi,eax //保存原字符串
  94. mov edx,[eax-4] //获得字符串长度
  95. test edx,edx //检查长度
  96. je @@Exit {Length(S) = 0}
  97. mov ecx,edx //保存长度
  98. Push ecx
  99. shl edx,1
  100. mov eax,esi
  101. {$IFDEF VER210}
  102. movzx ecx, word ptr [edi-12] {需要设置CodePage}
  103. {$ENDIF}
  104. call System.@LStrSetLength //设置新串长度
  105. mov eax,esi //新字符串地址
  106. Call UniqueString //产生一个唯一的新字符串,串位置在eax中
  107. Pop ecx
  108. @@SetHex:
  109. xor edx,edx //清空edx
  110. mov dl, [edi] //Str字符串字符
  111. mov ebx,edx //保存当前的字符
  112. shr edx,4 //右移4字节,得到高8位
  113. mov dl,byte ptr[edx+@@HexChar] //转换成字符
  114. mov [eax],dl //将字符串输入到新建串中存放
  115. and ebx,$0F //获得低8位
  116. mov dl,byte ptr[ebx+@@HexChar] //转换成字符
  117. inc eax //移动一个字节,存放低位
  118. mov [eax],dl
  119. inc edi
  120. inc eax
  121. loop @@SetHex
  122. @@Exit:
  123. pop edi
  124. pop esi
  125. pop ebx
  126. ret
  127. @@HexChar: db '0123456789ABCDEF'
  128. end;
  129. function HexToStr(const Str: AnsiString): AnsiString;
  130. asm
  131. push ebx
  132. push edi
  133. push esi
  134. test eax,eax //为空串
  135. jz @@Exit
  136. mov edi,eax
  137. mov esi,edx
  138. mov edx,[eax-4]
  139. test edx,edx
  140. je @@Exit
  141. mov ecx,edx
  142. push ecx
  143. shr edx,1
  144. mov eax,esi //开始构造字符串
  145. {$IFDEF VER210}
  146. movzx ecx, word ptr [edi-12] {需要设置CodePage}
  147. {$ENDIF}
  148. call System.@LStrSetLength //设置新串长度
  149. mov eax,esi //新字符串地址
  150. Call UniqueString //产生一个唯一的新字符串,串位置在eax中
  151. Pop ecx
  152. xor ebx,ebx
  153. xor esi,esi
  154. @@CharFromHex:
  155. xor edx,edx
  156. mov dl, [edi] //Str字符串字符
  157. cmp dl, '0' //查看是否在0到f之间的字符
  158. JB @@Exit //小于0,退出
  159. cmp dl,'9' //小于=9
  160. ja @@DoChar//CompOkNum
  161. sub dl,'0'
  162. jmp @@DoConvert
  163. @@DoChar:
  164. //先转成大写字符
  165. and dl,$DF
  166. cmp dl,'F'
  167. ja @@Exit //大于F退出
  168. add dl,10
  169. sub dl,'A'
  170. @@DoConvert: //转化
  171. inc ebx
  172. cmp ebx,2
  173. je @@Num1
  174. xor esi,esi
  175. shl edx,4
  176. mov esi,edx
  177. jmp @@Num2
  178. @@Num1:
  179. add esi,edx
  180. mov edx,esi
  181. mov [eax],dl
  182. xor ebx,ebx
  183. inc eax
  184. @@Num2:
  185. dec ecx
  186. inc edi
  187. test ecx,ecx
  188. jnz @@CharFromHex
  189. @@Exit:
  190. pop esi
  191. pop edi
  192. pop ebx
  193. end;
  194. procedure TCACaseFrm.btn3Click(Sender: TObject);
  195. var
  196. d, k, d1, k2: string;
  197. begin
  198. k := 'asdf';
  199. d := '32324sdfas';
  200. // d1 := Encrypt(d, k);
  201. // ShowMessage(d1);
  202. ShowMessage(DecryptNoHex(HexToStr(
  203. '48BE536245C22280C1F1899C9C28D0E7646F267CA61C4DFBAD0107A7FF33E22A83A5D2394F8FD405C26FF401'),
  204. 'B0F0E1308c2111EF92E995795A3DED427AE31A14DEB647059A31073F1D641752'));
  205. // ShowMessage(Decrypt(d1, k));
  206. end;
  207. procedure TCACaseFrm.btn4Click(Sender: TObject);
  208. begin
  209. Authenticate1(PChar('hellow'), PChar(111));
  210. end;
  211. function SplitString(const Source,Ch:string):TStringList;
  212. var
  213. Temp: string;
  214. iLoop: Integer;
  215. begin
  216. Result := TStringList.Create;
  217. Temp := Source;
  218. iLoop := Pos(Ch, Source);
  219. while iLoop <> 0 do
  220. begin
  221. Result.Add(copy(temp, 0, iLoop-1));
  222. Delete(temp, 1, iLoop);
  223. iLoop := Pos(Ch, Temp);
  224. end;
  225. Result.Add(temp);
  226. end;
  227. procedure TCACaseFrm.OnRedirect(Sender: TObject; var dest: string; var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
  228. const
  229. TOKEN: string = 'access_token=';
  230. CLIENT_KEY: string = 'clientkey=';
  231. var
  232. AParamsStr: string;
  233. AParams: TStrings;
  234. iStart, iEnd, iCount, i: Integer;
  235. begin
  236. if NumRedirect = 3 then
  237. begin
  238. AParamsStr := dest;
  239. AParams := SplitString(AParamsStr, '&');
  240. try
  241. for i := 0 to AParams.Count - 1 do
  242. begin
  243. iStart := Pos(TOKEN, AParams[i]);
  244. if iStart > 0 then
  245. begin
  246. Inc(iStart, Length(TOKEN));
  247. (Sender as TAuthIdHTTP).FAccessToken := Copy(AParams[i], iStart);
  248. Break;
  249. end;
  250. end;
  251. for i := 0 to AParams.Count - 1 do
  252. begin
  253. iStart := Pos(CLIENT_KEY, AParams[i]);
  254. if iStart > 0 then
  255. begin
  256. Inc(iStart, Length(CLIENT_KEY));
  257. (Sender as TAuthIdHTTP).FClientKey := Copy(AParams[i], iStart);
  258. Break;
  259. end;
  260. end;
  261. finally
  262. AParams.Free;
  263. end;
  264. end;
  265. end;
  266. function TCACaseFrm.DecodeAdapter(AData, AKey: string): string;
  267. const
  268. TICKET_TAG: string = 'ticket=';
  269. EXTEND_TAG: string = 'extend=';
  270. ID_TAG: string = 'id=';
  271. var
  272. AResults: TStrings;
  273. AResultStr, ATicket, AExtend, AID: string;
  274. iStart, iEnd, iCount, i: Integer;
  275. jo: ISuperObject;
  276. begin
  277. AResultStr := (Decrypt(AData, AKey));
  278. if AResultStr = '' then
  279. begin
  280. ShowMessage('错误:解密失败.');
  281. Exit;
  282. end;
  283. AResults := SplitString(AResultStr, '&');
  284. try
  285. for i := 0 to AResults.Count - 1 do
  286. begin
  287. iStart := Pos(TICKET_TAG, AResults[i]);
  288. if iStart > 0 then
  289. begin
  290. Inc(iStart, Length(TICKET_TAG));
  291. ATicket := Copy(AResults[i], iStart);
  292. Break;
  293. end;
  294. end;
  295. for i := 0 to AResults.Count - 1 do
  296. begin
  297. iStart := Pos(EXTEND_TAG, AResults[i]);
  298. if iStart > 0 then
  299. begin
  300. Inc(iStart, Length(EXTEND_TAG));
  301. AExtend := Copy(AResults[i], iStart);
  302. Break;
  303. end;
  304. end;
  305. for i := 0 to AResults.Count - 1 do
  306. begin
  307. iStart := Pos(ID_TAG, AResults[i]);
  308. if iStart > 0 then
  309. begin
  310. Inc(iStart, Length(ID_TAG));
  311. AID := Copy(AResults[i], iStart);
  312. Break;
  313. end;
  314. end;
  315. if (AID = '') or (ATicket = '') then
  316. begin
  317. ShowMessage('错误:解密失败,找不到关键信息.');
  318. Exit;
  319. end;
  320. jo := SO('{}');
  321. jo.I['ticket'] := StrToInt64(ATicket);
  322. jo.S['id'] := AID;
  323. jo.S['extend'] := AExtend;
  324. Result := jo.AsJSon();
  325. finally
  326. AResults.Free;
  327. end;
  328. end;
  329. function TCACaseFrm.Authenticate(AAuthURL, AAppSecret: PChar): PChar;
  330. const
  331. GET_OPENKEY: string = 'http://%s:%s/api/oauth/me?access_token=%s';
  332. var
  333. AIdHttp: TAuthIdHTTP;
  334. AURL, AToken, AClientKey,
  335. ASecret,
  336. AOpenKey: string;
  337. AHost: string;
  338. joStr: string;
  339. jo: ISuperObject;
  340. AIDURL: TIdURI;
  341. begin
  342. AURL := string(AAuthURL);
  343. ASecret := string(AAppSecret);
  344. AIdHttp := TAuthIdHTTP.Create(nil);
  345. AIDURL := TIdURI.Create(AURL);
  346. try
  347. AIdHttp.RedirectMaximum := 5;
  348. AIdHttp.HandleRedirects := True;
  349. AIdHttp.OnRedirect := OnRedirect;
  350. AIdHttp.Get(AURL);
  351. if (Length(AIdHttp.FAccessToken) = 0) or (Length(AIdHttp.FAccessToken) <> 32) then
  352. begin
  353. ShowMessage('错误:没有获取到通行证或不是有效的通行证,可能是因为认证链接已经过期.');
  354. Exit;
  355. end;
  356. if (Length(AIdHttp.FClientKey) = 0) then
  357. begin
  358. ShowMessage('错误:您还没有绑定该应用的账号,请联系管理员绑定.');
  359. Exit;
  360. end;
  361. AClientKey := AIdHttp.FClientKey;
  362. AToken := AIdHttp.FAccessToken;
  363. AURL := Format(GET_OPENKEY, [AIDURL.Host, AIDURL.Port, AToken]);
  364. joStr := Utf8ToAnsi(AIdHttp.Get(AURL));
  365. if joStr = '' then
  366. begin
  367. ShowMessage('错误:不能获取OpenKey.');
  368. Exit;
  369. end;
  370. jo := SO(joStr);
  371. if jo = nil then
  372. begin
  373. ShowMessage('错误:OpenKey格式错误.');
  374. Exit;
  375. end;
  376. AOpenKey := jo.S['openkey'];
  377. if AOpenKey = '' then
  378. begin
  379. ShowMessage('错误:OpenKey为null.');
  380. Exit;
  381. end;
  382. try
  383. Result := PChar(DecodeAdapter(AClientKey, (string(ASecret) + AOpenKey)));
  384. except
  385. on Ex: Exception do
  386. begin
  387. ShowMessage('错误:解密异常,' + Ex.Message + '.');
  388. Result := nil;
  389. end;
  390. end;
  391. finally
  392. AIdHttp.Free;
  393. AIDURL.Free;
  394. end;
  395. end;
  396. function TCACaseFrm.DecodeClientKey(AOpenKey, AAppSecret, AClientKey: string): string;
  397. begin
  398. end;
  399. procedure TCACaseFrm.FormCreate(Sender: TObject);
  400. begin
  401. wbrwsrwth1.Navigate(ExtractFilePath(paramstr(0)) + '111.html');
  402. end;
  403. end.