delphi 给程序添加“伪”数字签名代码的优化  
官方Delphi 学习QQ群: 682628230(三千人)
频道

delphi 给程序添加“伪”数字签名代码的优化


 

最近看了某位仁兄的给程序添加数字签名的delphi代码,其中里面的文件流的使用让人感觉很高深,其实还有一种更加简单的方法,下面是我修改后的代码:

 
  1. function AddDigiSignFromFile(const FormFile, ToFile: string): Boolean;//添加数字签名
  2. var
  3. vFileSZQMDZ: Integer;//指定数字签名的地址
  4. vSZQMDZ: Integer; //数字签名地址
  5. vBufSize: Integer;//数字签名大小
  6. vFS: TFileStream;
  7. vBufAttr: array of Byte;
  8. vSize: Integer;
  9. begin
  10. Result := False;
  11. if not FileExists(ToFile) then
  12. Exit;
  13. try
  14. vFS := TFileStream.Create(FormFile, fmOpenRead);
  15. try
  16. vFS.Position:= $3C;
  17. vFS.ReadBuffer(vFileSZQMDZ, SizeOf(vFileSZQMDZ));
  18. Inc(vFileSZQMDZ, $98) ; //数字签名地址
  19. vFS.Position:= vFileSZQMDZ;
  20. vFS.ReadBuffer(vSZQMDZ, SizeOf(vSZQMDZ)); //得到记录数字签名所在地的缓冲区地址
  21. vFS.ReadBuffer(vBufSize, SizeOf(vBufSize)); //得到记录数字签名缓冲区大小
  22. vFS.Position:= vSZQMDZ;
  23. SetLength(vBufAttr, vBufSize);
  24. vFS.ReadBuffer(vBufAttr[0], vBufSize); //读取数字签名数据到vbufattr
  25. finally
  26. vFS.Free;
  27. end;
  28. vFS := TFileStream.Create(ToFile, fmOpenReadWrite);
  29. try
  30. vFS.Position:= $3C;
  31. vFS.ReadBuffer(vFileSZQMDZ, SizeOf(vFileSZQMDZ));
  32. Inc(vFileSZQMDZ, $98) ; //数字签名地址
  33. vFS.Position:= vFileSZQMDZ;
  34. vSize := vFS.Size;
  35. vFS.WriteBuffer(vSize, SizeOf(vSize)); //写入数据指定数字签名所在地
  36. vFS.WriteBuffer(vBufSize, SizeOf(vBufSize)); //写入数据指定数字签名大小
  37. vFS.Position:= vFS.Size;
  38. vFS.WriteBuffer(vBufAttr[0], vBufSize);
  39. finally
  40. vFS.Free;
  41. end;
  42. Result := True;
  43. except
  44. end;
  45. end;

原来的代码如下:

view plaincopy to clipboardprint?
  1. function ReadHexDZ(fvFileName:string; fvHexDZ:Integer):Integer; //读取指定偏移地址十六进制数据
  2. var
  3. //vBuffer : array of byte; //没指定长度的话调用函数回出错
  4. vBuffer : array [0..3] of byte; //指定长度
  5. vInt : integer;
  6. vFS : TFileStream;
  7. vStr : string;
  8. begin
  9. Result := -1 ;
  10. vStr:= '';
  11. try
  12. vFS:= TFileStream.Create(fvFileName, fmOpenRead); //以读取方式打开
  13. vFS.Position:= fvHexDZ; //设置开始位置
  14. vFS.ReadBuffer(vBuffer, SizeOf(vBuffer)); //读取数据到缓冲区
  15. for vInt:=0 to 3 do
  16. vStr:=IntToHex(vBuffer[vInt], 2) + vStr; //得到16进制
  17. Result:= StrToInt('$'+vStr) ;
  18. except
  19. Result := -1
  20. END;
  21. vFS.Free;
  22. end;
  23. procedure TForm1.Button4Click(Sender: TObject);
  24. var
  25. vFile1, vFile2: string;
  26. vBuf1,vBuf2: array [0..3] of Byte;
  27. vFS: TFileStream;
  28. vBufAttr: array [0..100000] of PAnsiChar ;
  29. vFile2SZQMDZ,
  30. vFile1SZQMDZ, //指定数字签名的地址
  31. vFile1SZQMSizeDZ, //指定数字签名大小
  32. vSZQMDZ, //数字签名地址
  33. vBufSize:integer;//数字签名大小
  34. vStr, vNewStr, vNewStr2:string;
  35. vInt: Integer;
  36. begin
  37. vFile1:= Trim(EFile1.Text);
  38. vFile2 := Trim(EFile2.Text);
  39. if not FileExists(vFile1) or not FileExists(vFile2) then
  40. begin
  41. ShowMessBox('消息', '找不到文件!');
  42. Exit;
  43. end;
  44. if CBbakFile.Checked then
  45. CopyFile(PAnsiChar(vFile2), PAnsiChar(ExtractFileName(vFile2)+'.bak'), False);
  46. vFile1SZQMDZ:= ReadHexDZ(vFile1, $3C) + $98 ; //数字签名地址
  47. vFile1SZQMSizeDZ := vFile1SZQMDZ +$4; //数字签名大小地址
  48. vSZQMDZ:= ReadHexDZ(vFile1, vFile1SZQMDZ); //数字签名开始位置
  49. vBufSize := ReadHexDZ(vFile1, vFile1SZQMSizeDZ) ;
  50. //ShowMessBox(IntToStr(vFile1SZQMSizeDZ), IntToStr(vBufSize));
  51. // exit;
  52. try
  53. vFS := TFileStream.Create(vFile1, fmOpenRead);
  54. try
  55. vFS.Position:= vFile1SZQMDZ;
  56. vFS.ReadBuffer(vBuf1, 4); //得到记录数字签名所在地的缓冲区
  57. vFS.Position:= vFile1SZQMSizeDZ;
  58. vFS.ReadBuffer(vBuf2, 4); //得到记录数字签名大小的缓冲区
  59. vFS.Position:= vSZQMDZ;
  60. vFS.ReadBuffer(vBufAttr, vBufSize); //读取数字签名数据到vbufattr
  61. finally
  62. vFS.Free;
  63. end;
  64. vFile2SZQMDZ := ReadHexDZ(vFile2, $3C) + $98;
  65. vFS := TFileStream.Create(vFile2, fmOpenReadWrite);
  66. try
  67. vFS.Position:= vFile2SZQMDZ;
  68. vStr:= IntToHex(vFS.Size, 8);
  69. vNewStr:= Copy(vStr, 7, 2) ;
  70. vNewStr:= vNewStr + Copy(vStr, 5, 2) ;
  71. vNewStr:= vNewStr + Copy(vStr, 3, 2) ;
  72. vNewStr:= vNewStr + Copy(vStr, 1, 2) ;
  73. vNewStr2:= '';
  74. for vInt:=1 to (length(vNewStr) div 2) do
  75. vNewStr2:=vNewStr2+char(strtoint('$'+copy(vNewStr,(vInt-1)*2+1,2)));
  76. vFS.WriteBuffer(Pointer(vNewStr2)^, 4); //写入数据指定数字签名所在地
  77. vFS.Position := vFile2SZQMDZ + $4;
  78. vFS.WriteBuffer(vbuf2, SizeOf(vBuf2)); //写入数据指定数字签名大小
  79. vFS.Position:= vFS.Size;
  80. vFS.WriteBuffer(vBufAttr, vBufSize);
  81. finally
  82. vFS.Free;
  83. end;
  84. ShowMessBox('消息','添加数字签名成功');
  85. except
  86. ShowMessBox('坏消息','添加数字签名出错');
  87. end;
  88. end;

其实那个ReadHexDZ函数没有什么必要,把整型以一个一个字节的形式读出来,然后连接起来又转换为整型,直接以整型的形式去读不就行了?不理解作者的意图-_-!。然后每次用ReadHexDZ都要打开一次文件,效率不高,其实完全可以打开一次文件做完所有的事。这只是我的一点分析,如有不足的地方还请指正。

复制数字签名以后这个程序的“属性”里面就会出现“数字签名”的选项卡,但是这种靠复制其它程序数字签名的方法是有问题的,因为这个不是程序本身的数字签名,所以即使复制了数字签名也会验证失败。Windows也会提示这个数字签名无效。所以这个只能骗过一些不知情的用户,对于有经验的用户这个反而说明了这个程序更加有问题。


推荐分享
图文皆来源于网络,内容仅做公益性分享,版权归原作者所有,如有侵权请告知删除!
 

Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号

执行时间: 0.045269966125488 seconds