一个vc写的dll 实现3des功能,调三个函数,头文件如下
DECL des_3EEEinit(UCHAR *key, int len, DES_KS ks1, DES_KS ks2, DES_KS ks3);
DECL des_ecb3EEEencode(UCHAR *in64, UCHAR *out64, DES_KS ks1, DES_KS ks2, DES_KS ks3);
DECL des_ecb3EEEdecode(UCHAR *in64, UCHAR *out64, DES_KS ks1, DES_KS ks2, DES_KS ks3);
其中
typedef unsigned long DES_KS[16][2];在delphi中调用此dlltype
kstype=array[1..16,1..2] of dword; //对应unsigned long DES_KS[16][2];
Function des_3EEEinit (key:pchar;len : integer;var ks1,ks2,ks3:kstype) : Longword ; cdecl ; external 'des3.dll' ;procedure TForm1.Button1Click(Sender: TObject);
var ks1,ks2,ks3:kstype;
key:pchar;
begin
key:= '123456789012345678901234';
des_3EEEinit(key,224,ks1,ks2,ks3);
end;出内存错误 不知道是因为pchar对应UCHAR *key的问题,还是那个二维数组的问题,请高手指教
dll,头文件,demo在此下载http://euploading.cn/file/23057/des3-win32-zip.html如能提供delphi版的3des算法,能够解密该dll加密的文件也可
DECL des_3EEEinit(UCHAR *key, int len, DES_KS ks1, DES_KS ks2, DES_KS ks3);
DECL des_ecb3EEEencode(UCHAR *in64, UCHAR *out64, DES_KS ks1, DES_KS ks2, DES_KS ks3);
DECL des_ecb3EEEdecode(UCHAR *in64, UCHAR *out64, DES_KS ks1, DES_KS ks2, DES_KS ks3);
其中
typedef unsigned long DES_KS[16][2];在delphi中调用此dlltype
kstype=array[1..16,1..2] of dword; //对应unsigned long DES_KS[16][2];
Function des_3EEEinit (key:pchar;len : integer;var ks1,ks2,ks3:kstype) : Longword ; cdecl ; external 'des3.dll' ;procedure TForm1.Button1Click(Sender: TObject);
var ks1,ks2,ks3:kstype;
key:pchar;
begin
key:= '123456789012345678901234';
des_3EEEinit(key,224,ks1,ks2,ks3);
end;出内存错误 不知道是因为pchar对应UCHAR *key的问题,还是那个二维数组的问题,请高手指教
dll,头文件,demo在此下载http://euploading.cn/file/23057/des3-win32-zip.html如能提供delphi版的3des算法,能够解密该dll加密的文件也可
解决方案 »
- 求教:俺确认Library里有路径,编译时就是要File not found
- 使用hjy2:=inttohex(hjy,4);方法假设得到2个(hjy2):1A 01 和 DE 21,那能推出这2个之前的10进制相差多少吗?
- 请问关于TWebBrowser的问题
- 向虚拟表添加记录出错 请大家来帮忙啊
- 一个关于web service的问题
- 请问大家在delphi中正弦,余弦,正切,反正切函数的函数是什么,我一时没查到
- 如何使一个Button变成一个图像,就好像Skin里面的button一样
- 怎样读取依次目录下所有文件(未知文件名)?
- 高手请进!!!关于打印!!!
- 一个关于报表的简单问题
- delphi 的 DBComboBox 控件好像有个BUG?!
- 取得iframe中iframe网页中textbox的值
按照EEE的加密方式
我做了三次DecryStrHex,对不上
#if defined(WIN32) || defined(OS2)
#define DECL int pascal
#define UCHAR unsigned char
#define SIZE_T size_t
#define DES_PKS DES_KS *
#endif /* WIN32 */pascal(其实应该写__pascal而好些)call就是stdcall
var ks1,ks2,ks3:kstype;
key:array[0..255] of char;
begin
key:= '123456789012345678901234';
des_3EEEinit(key,224,ks1,ks2,ks3);
end;
这样试试
难道跟delphi版本有关系?我是delphi7
参数传的没问题,虽然文件里说最大传的len是24,我试着传224也返回0,按照文档中的说明也算是正常初始化了。
报错的原因是一开始cdecl调用约定,本来被调用方已经清理了栈,但cdecl的调用方又清理了一遍,栈指针被破坏了就出错了
des_ecb3EEEencode(UCHAR *in64, UCHAR *out64, DES_KS ks1, DES_KS ks2, DES_KS ks3); 还是不行
function des_ecb3EEEdecode(in64:pchar;var out64:pchar;ks1,ks2,ks3:kstype):Longword;stdcall;external 'DES3.dll';
var ks1,ks2,ks3:kstype;
key,out64:pchar;
a:integer;
begin
key:= 'D352C02CADD98FA7C9A8E1F9';
des_3EEEinit(key,24,ks1,ks2,ks3);
a:=des_ecb3EEEdecode('A03E951B',out64,ks1,ks2,ks3); //返回值=0,看似没问题
showmessage(out64); //取的时候出错。
//unsigned long DES_KS[16][2];
TDES_KS = array [0..16-1, 0..2-1] of LongWord;//DECL des_3EEEinit(UCHAR *key, int len, DES_KS ks1, DES_KS ks2, DES_KS ks3);
procedure des_3EEEinit(key: (*PByte*) PAnsiChar; len: Integer; const ks1,ks2,ks3); cdecl; external 'des3.dll' ;
{//或者
procedure des_3EEEinit(key: (*PByte*) PAnsiChar; len: Integer; ks1,ks2,ks3: TDES_KS); cdecl; external 'des3.dll' ;
}
//DECL des_ecb3EEEencode(UCHAR *in64, UCHAR *out64, DES_KS ks1, DES_KS ks2, DES_KS ks3);
procedure des_ecb3EEEencode(in64: (*PByte*) PAnsiChar; out64: (*PByte*) PAnsiChar; const ks1,ks2,ks3); cdecl; external 'des3.dll' ;
{//或者
procedure des_ecb3EEEencode(in64: (*PByte*) PAnsiChar; out64: (*PByte*) PAnsiChar; const ks1,ks2,ks3: TDES_KS); cdecl; external 'des3.dll' ;
}
//DECL des_ecb3EEEdecode(UCHAR *in64, UCHAR *out64, DES_KS ks1, DES_KS ks2, DES_KS ks3);
procedure des_ecb3EEEdecode(in64: (*PByte*) PAnsiChar; out64: (*PByte*) PAnsiChar; const ks1,ks2,ks3); cdecl; external 'des3.dll' ;
{//或者
procedure des_ecb3EEEdecode(in64: (*PByte*) PAnsiChar; out64: (*PByte*) PAnsiChar; const ks1,ks2,ks3: TDES_KS); cdecl; external 'des3.dll' ;
}
procedure TForm1.Button1Click(Sender: TObject);
var ks1,ks2,ks3:TDES_KS;
key:PAnsiChar;
begin
key:= '123456789012345678901234';
des_3EEEinit(key,224,ks1,ks2,ks3);
end;
个人以为,这个Init实际上是把一个Key串初始化为三个DES_key_schedule,并通过参数分别返回给ks1,ks2,ks3,所以这里的三个参数不太可能是:
DECL des_3EEEinit(UCHAR *key, int len, DES_KS ks1, DES_KS ks2, DES_KS ks3);
而应当是
DECL des_3EEEinit(UCHAR *key, int len, DES_KS &ks1, DES_KS &ks2, DES_KS &ks3);
从而上面的代码应该改为:type
//unsigned long DES_KS[16][2];
TDES_KS = array [0..16-1, 0..2-1] of LongWord;//DECL des_3EEEinit(UCHAR *key, int len, DES_KS &ks1, DES_KS &ks2, DES_KS &ks3);
procedure des_3EEEinit(key: (*PByte*) PAnsiChar; len: Integer; var ks1,ks2,ks3); cdecl; external 'des3.dll' ;
{或者
procedure des_3EEEinit(key: (*PByte*) PAnsiChar; len: Integer; var ks1,ks2,ks3:TDES_KS); cdecl; external 'des3.dll' ;
}
//DECL des_ecb3EEEencode(UCHAR *in64, UCHAR *out64, DES_KS ks1, DES_KS ks2, DES_KS ks3);
procedure des_ecb3EEEencode(in64: (*PByte*) PAnsiChar; out64: (*PByte*) PAnsiChar; const ks1,ks2,ks3); cdecl; external 'des3.dll' ;
{//或者
procedure des_ecb3EEEencode(in64: (*PByte*) PAnsiChar; out64: (*PByte*) PAnsiChar; const ks1,ks2,ks3: TDES_KS); cdecl; external 'des3.dll' ;
}
//DECL des_ecb3EEEdecode(UCHAR *in64, UCHAR *out64, DES_KS ks1, DES_KS ks2, DES_KS ks3);
procedure des_ecb3EEEdecode(in64: (*PByte*) PAnsiChar; out64: (*PByte*) PAnsiChar; const ks1,ks2,ks3); cdecl; external 'des3.dll' ;
{//或者
procedure des_ecb3EEEdecode(in64: (*PByte*) PAnsiChar; out64: (*PByte*) PAnsiChar; const ks1,ks2,ks3: TDES_KS); cdecl; external 'des3.dll' ;
}
procedure TForm1.Button1Click(Sender: TObject);
var ks1,ks2,ks3:TDES_KS;
key:PAnsiChar;
begin
key:= '123456789012345678901234';
des_3EEEinit(key,224,ks1,ks2,ks3);
end;
des_3EEEinit(key,224,ks1,ks2,ks3);
在delphi中,不支持用固定数组作参数的语法,必须另声明类型才能传;而动态数组作参数的话,又不止传了一个首地址,还传了一个High()。c/cpp的编译器自动会把数组形式的参数退化成指针的形式([] -> *,这里不是C语言版,我就不多说了),而且也只传了一个首地址而已,两者之间差太多了,你说delphi“也是”就不知道该怎么讲了
var ks1,ks2,ks3:kstype;
key:pchar;
begin
key:= '123456789012345678901234';
GetMem(ks1, 1024); // 分配内存空间
GetMem(ks2, 1024);
GetMem(ks3, 1024);
des_3EEEinit(key,224,ks1,ks2,ks3);
FreeMem(ks1); // 释放内存空间
FreeMem(ks2);
FreeMem(ks3);
end; 楼主,请看红色代码部分,如果好用的话,记得给分噢,谢谢!
按照windows的约定,为避免歧义dll都是用c表达的,而且也方便翻译成各种语言。我还真没听过有哪门子正经用c++的dll写个c不认的声明,directx、gdi+都老老实实按c写的您要是认为我不用c++就谈不出结果,那大可以到newsmth.net的C版啊、C++版啊、programming版啊、msdn版之类的相关版面谈谈您的高见,那里的水平比csdn高多了,肯定能谈出结果来。不过那里即使c++用的很好的,也没几个自称懂c++的,可千万别以为他们真没你懂
DECL des_3EEEinit(UCHAR *key, int len, DES_KS ks1, DES_KS ks2, DES_KS ks3);
按照直面的转换为delphi的声明
function des_3EEEinit(key: PByte; len: Integer; ks1, ks2, ks3: DES_KS): Integer; winapi;
对于高版本的Delphi编译器(默认为传值),则等同于
function des_3EEEinit(key: PByte; len: Integer; const ks1, ks2, ks3: DES_KS): Integer; winapi;
这对于使用者来讲,可能会认为ks1,ks2,ks3都为入参,则第一直觉将会是函数不会对这些参数做出修改,从而可能会传入一个const定义,或者原值需要复用的参数,则会存在一定的误导或者不明确性。C++之所以引入“引用”也是出于明确目的。DECL des_3EEEinit(UCHAR *key, int len, DES_KS ks1, DES_KS ks2, DES_KS ks3);
DECL des_3EEEinit(UCHAR *key, int len, DES_KS *ks1, DES_KS *ks2, DES_KS *ks3);
DECL des_3EEEinit(UCHAR *key, int len, DES_KS &ks1, DES_KS &ks2, DES_KS &ks3);
这三种定义对于C/C++使用者是等价的,相比最后的定义更为明确同时也更适合C/C++以外的使用者理解及声明转换。另外,实际上使用VC编译器编译出来的也不再是标准C当中的pascal Calling Convention,而是stdcall(或称WINAPI) Calling Convention。其它的问题就不再扯远了,刚下载了Source看了一下,给出一个Delphi当中相应的定义
type
DES_KS = array [0..16-1, 0..2-1] of LongWord;function des_3EEEinit(const key: PAnsiChar;const len: Integer;var ks1, ks2, ks3: DES_KS ): Integer; stdcall {WINAPI}; external 'des3.dll';
function des_ecb3EEEencode(const in64: PAnsiChar; out64: PAnsiChar; const ks1, ks2, ks3: DES_KS): Integer; stdcall {WINAPI}; external 'des3.dll';
function des_ecb3EEEdecode(const in64: PAnsiChar; out64: PAnsiChar; const ks1, ks2, ks3: DES_KS): Integer; stdcall {WINAPI}; external 'des3.dll';
最大的问题是pchar和pbyte的问题
用ollydbg查看堆栈指针,逐个比较ecb3EEEencode的参数,终于解决另外用delphi版的des算法也没问题了
3des的eee算法,加密时,用三个8位的key,依次对数据加密
但是delhpi版的des算法,key长度不够的话,没有用0填充,我的第一个key只有三位
搞一个24位的byte数组,其余21位用0填充后解决总结一下这类问题,如果对语言不熟悉,多用调试工具仔细看堆栈,比猜测更重要