Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从本机COM调用use.NET RijndaelManaged?_.net_Winapi_Com_Rijndael - Fatal编程技术网

如何从本机COM调用use.NET RijndaelManaged?

如何从本机COM调用use.NET RijndaelManaged?,.net,winapi,com,rijndael,.net,Winapi,Com,Rijndael,有人能给出使用COM从本机Win32使用的示例用法吗 下面是一个如何使用.NET的函数示例 注意:这是一个如何将SHA256Managed和not称为RijndaelManaged**的示例。我展示这段代码是为了介绍使用早期和晚期绑定调用COM对象的一些棘手概念,并说明使用COM可调用包装器调用.NET对象是可能的。当听到我想混合使用.NET和Win32 COM时,有些人可能会举手示意 注意:语言是Delphi(我就是用Delphi编写和测试的),但为了让它看起来更像C#或Java,进行了代码

有人能给出使用COM从本机Win32使用的示例用法吗


下面是一个如何使用.NET的函数示例

注意:这是一个如何将SHA256Managed和not称为RijndaelManaged**的示例。我展示这段代码是为了介绍使用早期和晚期绑定调用COM对象的一些棘手概念,并说明使用COM可调用包装器调用.NET对象是可能的。当听到我想混合使用.NET和Win32 COM时,有些人可能会举手示意

注意:语言是Delphi(我就是用Delphi编写和测试的),但为了让它看起来更像C#或Java,进行了代码转换,因此问题更容易被更广泛的受众接受:

public static string HashStr256(String szPlaintext)
{
   OleVariant sha = CreateOleObject('System.Security.Cryptography.SHA256Managed');

   OleVariant inputBuffer = VarByteArrayOf(szPlaintext);

   Integer l = VarArrayLowBound(inputBuffer, 1);
   Integer h = VarArrayHighBound(inputBuffer, 1);

   ICryptoTransform crypto = IDispatch(sha) as ICryptoTransform;
   crypto.TransformFinalBlock(
         PSafeArray(TVarData(inputBuffer).VArray), //inputArray,
         l,  //input array offset
         h-l+1); //input array count

   OleVariant digest := sha.Hash;

   Result := ToBase64String(BytesOfVarByteArray(digest));
end;
使用helper函数:

function VarByteArrayOf(const s: string): OleVariant;
var
    Data: Pointer;
begin
    //Create variant byte array to hold the bytes
    Result := VarArrayCreate([0, Length(s)-1], varByte);

    //Copy from Delphi array to Variant Array
    if Length(s) > 0 then
    begin
        Data := VarArrayLock(Result);
        try
            System.Move(s[1], Data^, Length(s));
        finally
            VarArrayUnlock(Result);
        end;
    end;
end;
我显示代码调用
SHA256Managed
的真正原因是为了演示在Delphi中将
数组
传递给COM时遇到的困难。例如,如果您仅仅依赖于
IDispatch
后期绑定:

sha: OleVariant;
inputBuffer: OleVariant;
...
sha.TransformFinalBlock(inputBuffer, i, count);
然后在运行时您得到的参数是不正确的;关于
IDispatch
后期绑定的某些内容不支持传递作为字节数组的
OleVariant

这就是为什么我必须传递
OleVariant
中的
safearray
。我们都知道a只是一个,我们关心的是会员:

除了尝试使用
IDispatch
传递一个
PSafeArray
之外,延迟绑定会导致Delphi抛出:

OLE自动化调用中不允许使用类型

这就是为什么我们被迫部分放弃
IDispatch
icryptortransform
早期绑定的后期绑定:

ICryptoTransform_Native = interface(IDispatch)
   ['{8ABAD867-F515-3CF6-BB62-5F0C88B3BB11}']
   ...
   function TransformFinalBlock(inputBuffer: PSafeArray; inputOffset: Integer; inputCount: Integer): PSafeArray; safecall;
   ...
end;

应该是这样吧?我们已经解决了如何将数组传递给COM.NET对象的问题?我现在应该准备好使用
Rijndael
;使用
psaarray
的早期绑定

这就是我们想要尝试的后期绑定:

OleVariant aes := CreateOleObject('System.Security.Cryptography.RijndaelManaged');

OleVariant keyBytes = VarByteArrayOf(Key);
aes.Key := key;
由于上述相同原因,该操作失败-无法将
OleVariant
数组传递给COM对象(参数不正确)

因此,我们应该使用的早期绑定,并将
键作为
PSafeArray
传递:

var
   symmetric: ISymmetricAlgorithm;
   aes: OleVariant;
   keyBytes: OleVariant;
begin
   aes := CreateOleObject('System.Security.Cryptography.RijndaelManaged');

   symmetric:= (IDispatch(aes) as ISymmetricAlgorithm;
   symmetric.Key := PSafeArray(TVarData(inputBuffer).VArray);
   ...
end;
除了没有接口;我编的

如果从
mscorelib.tlb
导入类型库,其中包含
ICryptoTransform
,则没有早期绑定。有一个后期绑定的
算法

IID__SymmetricAlgorithm: TGUID = '{05BC0E38-7136-3825-9E34-26C1CF2142C9}';
CLASS_SymmetricAlgorithm: TGUID = '{5B67EA6B-D85D-3F48-86D2-8581DB230C43}';
_SymmetricAlgorithm = interface;
SymmetricAlgorithm = _SymmetricAlgorithm;

_SymmetricAlgorithm = interface(IDispatch)
   ['{05BC0E38-7136-3825-9E34-26C1CF2142C9}']
end;
_SymmetricAlgorithmDisp = dispinterface
   ['{05BC0E38-7136-3825-9E34-26C1CF2142C9}']
end;
那么如何从本机Win32 COM设置RijndaelManaged键和IV键呢?我可以使用什么后期绑定语法

如何从本机COM调用use.NET RijndaelManaged

进一步的尝试 由于没有可以使用的早期绑定
接口
,因此我必须关注如何通过
IDispatch
传递字节数组。秘密在于我传递给COM对象的
变量中应该有什么

由于早期绑定版本使用了safearrays
safearrays
,我将从它开始。首先,我将自己手动设置
OleVariant
结构

对于以下每一次尝试,以下是正确的:

key: OleVariant;
data: PSafeArray;

data := PSafeArray(TVarData(keyBytes).VArray);
设置

  • 尝试1
    VT\u数组
    安全数组指针

  • 尝试2
    VT\u数组
    安全数组指针

  • 尝试3
    VT\u安全阵列
    安全阵列。在变体中使用VT_数组

  • 尝试4
    VT\u安全阵列
    安全阵列。在变体中使用VT_数组

所有这些都失败,参数不正确,出现
错误

我感觉到,
VT_数组
(安全数组)和
VT_安全数组
(安全数组)并不是COM可调用包装器IDispatch接口准备接受的。也许它需要是
VT\u CARRAY

也许不是。也许比我聪明的人能弄明白

额外阅读 从本质上讲,这是我2008年在Borland新闻组上提出的一个问题的重新表述


您会将答案移动到一个答案中并接受它吗?如果你不这样做,那么我将不得不以NARQ的形式结束这个问题。在第一条水平规则之后,很难看出问题的答案。@IanBoyd,你为什么要使用.Net加密类而不是本机类?@IanBoyd,如果你愿意,我可以使用以下命令发布一个示例:)@WarrenP你可以从窗台上后退;我删除了
Delphi
标记。使用加密API或第三方库也不是我的问题。这个问题适用于任何本机代码程序员,甚至是汇编语言。您会将答案移动到一个答案并接受它吗?如果你不这样做,那么我将不得不以NARQ的形式结束这个问题。在第一条水平规则之后,很难看出问题的答案。@IanBoyd,你为什么要使用.Net加密类而不是本机类?@IanBoyd,如果你愿意,我可以使用以下命令发布一个示例:)@WarrenP你可以从窗台上后退;我删除了
Delphi
标记。使用加密API或第三方库也不是我的问题。这个问题适用于任何本机代码程序员,甚至是汇编语言。
IID__SymmetricAlgorithm: TGUID = '{05BC0E38-7136-3825-9E34-26C1CF2142C9}';
CLASS_SymmetricAlgorithm: TGUID = '{5B67EA6B-D85D-3F48-86D2-8581DB230C43}';
_SymmetricAlgorithm = interface;
SymmetricAlgorithm = _SymmetricAlgorithm;

_SymmetricAlgorithm = interface(IDispatch)
   ['{05BC0E38-7136-3825-9E34-26C1CF2142C9}']
end;
_SymmetricAlgorithmDisp = dispinterface
   ['{05BC0E38-7136-3825-9E34-26C1CF2142C9}']
end;
key: OleVariant;
data: PSafeArray;

data := PSafeArray(TVarData(keyBytes).VArray);
TVarData(key).VType := VT_ARRAY;
TVarData(key).VArray := data;
TVarData(key).VType := VT_ARRAY or VT_I1;
TVarData(key).VArray := data;
TVarData(key).VType := VT_SAFEARRAY or VT_I1;
TVarData(key).VArray := data;
TVarData(key).VType := VT_SAFEARRAY;
TVarData(key).VArray := data;