谁能给用法示例使用System.Security.Cryptography.RijndaelManaged
使用COM从本地Win32?
下面是如何使用.NET的功能例如System.Security.Cryptography.SHA256Managed
注 :这是如何调用SHA256Managed一个例子,而不是 RijndaelManaged的**。 我显示此代码来介绍一些调用COM对象与棘手的概念,早期和晚期绑定,并表明与调用COM调用包装.NET对象是可能的。 有些人可能会扔了那听到的时候我的手想混合.NET和Win32 COM。
注:语言是德尔福(这是我写的和测试它),而转码,使它看上去稍微更象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;
随着辅助函数:
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
是证明通过当我遇到困难arrays
,以COM在Delphi中。 例如,如果你单纯倚重IDispatch
后期绑定:
sha: OleVariant;
inputBuffer: OleVariant;
...
sha.TransformFinalBlock(inputBuffer, i, count);
然后,在运行时,你得到的参数不正确 ; 一些关于IDispatch
后期绑定不支持将一个OleVariant
是字节数组。
这就是为什么我要,而不是通过safearray
是内部OleVariant
。 正如我们都知道的一个变体仅仅是一个联合结构 ,我们关心的SAFEARRAY
成员:
data: PSafeArray;
data := PSafeArray(TVarData(inputBuffer).VArray);
sha.TransformFinalBlock(data, i, count);
除了试图通过一个PSafeArray
使用IDispatch
后期绑定的原因德尔福投掷了:
不允许的类型在OLE自动调用
这就是为什么我们不得不放弃一部分IDispatch
后期绑定ICryptoTransform
早期绑定:
ICryptoTransform_Native = interface(IDispatch)
['{8ABAD867-F515-3CF6-BB62-5F0C88B3BB11}']
...
function TransformFinalBlock(inputBuffer: PSafeArray; inputOffset: Integer; inputCount: Integer): PSafeArray; safecall;
...
end;
同
crypto: ICryptoTransform;
sha: OleVariant;
inputBuffer: OleVariant;
crypto = IDispatch(sha) as ICryptoTransform;
crypto.TransformFinalBlock(
PSafeArray(TVarData(inputBuffer).VArray), //inputArray,
i, n);
所以这应该是它,对吗? 我们已经解决了如何将数组传递给COM .NET对象? 我应该是所有设置为使用Rijndael
现在; 使用带有早期绑定PSafeArray
。
这就是我们想尝试用后期绑定:
OleVariant aes := CreateOleObject('System.Security.Cryptography.RijndaelManaged');
OleVariant keyBytes = VarByteArrayOf(Key);
aes.Key := key;
失败对于上述同样的原因-你不能传递OleVariant
阵列COM对象(参数不正确)。
所以,我们应该只使用的早期绑定SymmetricAlgorithm.Key
并通过Key
的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;
除了没有ISymmetricAlgorithm
接口; 我做到了起来。
如果从导入类型库mscorelib.tlb
,其中包含ICryptoTransform
,没有早期绑定ISymmetricAlgorithm
。 有一个后期绑定 ISymmetricAlgorithm
:
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;
所以,我怎么可以设置RijndaelManaged的 Key
和IV
从本地Win32 COM? 我可以使用什么样的后期绑定语法?
如何从本地COM调用.NET使用RijndaelManaged的?
进一步尝试
由于没有早期绑定interface
我可以使用,我必须集中在如何通过传递一个字节数组IDispatch
。 秘密就在于应该在什么Variant
,我传递给COM对象。
由于早期绑定版本中使用safearrays
,我将着手行动。 首先,我将手动设置OleVariant
构建自己。
对于每一个下面的尝试以下情况:
key: OleVariant;
data: PSafeArray;
data := PSafeArray(TVarData(keyBytes).VArray);
设置变种枚举自己 。
试图1:
VT_ARRAY
甲SAFEARRAY指针。TVarData(key).VType := VT_ARRAY; TVarData(key).VArray := data;
尝试2:
VT_ARRAY
甲SAFEARRAY指针。TVarData(key).VType := VT_ARRAY or VT_I1; TVarData(key).VArray := data;
尝试3:
VT_SAFEARRAY
安全数组。 在VARIANT使用VT_ARRAY。TVarData(key).VType := VT_SAFEARRAY or VT_I1; TVarData(key).VArray := data;
尝试4:
VT_SAFEARRAY
安全数组。 在VARIANT使用VT_ARRAY。TVarData(key).VType := VT_SAFEARRAY; TVarData(key).VArray := data;
他们都失败了The parameter is incorrect
的错误。
得到我得到这个意义上, VT_ARRAY
(一个SAFEARRAY)和VT_SAFEARRAY
(一个SAFEARRAY)绝对不会和COM调用包装IDispatch接口就是准备接受。 也许它需要VT_CARRAY
。
或者可能不是。 也许有人比我聪明可以计算出来。
奖金阅读
这是本质上,我提出的问题在2008年Borland的新闻组的重新措辞
Delphi编译器已经内置的COM SAFEARRAYS的知识呢?
- .NET MSHTML:如何通过一个BSTR SAFEARRAY?