【问题标题】:P/Invoking CryptImportKey and marshaling structsP/Invoking CryptImportKey 和封送结构
【发布时间】:2009-02-05 19:52:39
【问题描述】:

我正在尝试从 C# P/Invoke 到 CryptImportKey 以设置一个已知密钥,然后再加密将在某个时候在 C++ Win32 服务中解密的数据。我有 P/Invoke 的方法签名,一切正常,但我无法让它接受我的密钥 blob。 C++ 结构在下面的 cmets 中,用于编组的 C# 结构在下面。

        // typedef struct _PUBLICKEYSTRUC 
    // {
    //    BYTE bType;  
    //    BYTE bVersion;  
    //    WORD reserved;  
    //    ALG_ID aiKeyAlg;
    // } BLOBHEADER, PUBLICKEYSTRUC;
    [StructLayout(LayoutKind.Sequential)]
    public struct PUBLICKEYSTRUC
    {
        public Byte bType;
        public Byte bVersion;
        public Int16 reserved;
        public Int32 aiKeyAlg;
    }

    //typedef struct __KEYBLOB 
    //{
    //    BLOBHEADER hdr;
    //    DWORD cbKeySize;
    //    BYTE* rgbKeyData;
    //} KEYBLOB;

    [StructLayout(LayoutKind.Sequential)]
    public struct KEYBLOB
    {
        public PUBLICKEYSTRUC hdr;
        public Int16 cbKeySize;
        public Byte[] rgbKeyData;
    }

然后我使用:

        int len = (Marshal.SizeOf(typeof(PUBLICKEYSTRUC) + Marshal.SizeOf(typeof(KEYBLOB)) + KeySize;
        byte[] arr = new byte[len];
        IntPtr ptr = Marshal.AllocHGlobal(len);
    Marshal.StructureToPtr(keyBlob, ptr, true);
    Marshal.Copy(ptr, arr, 0,len);
        Marshal.FreeHGlobal(ptr);

要进入一个字节数组以传递给 CryptImportKey,但它似乎从来没有带走密钥,当我用它加密时,我得到不同的密文时间,表明它没有使用我的密钥。

编辑:

密钥 blob 来自我拥有的可以成功加密和解密数据的 C++ 代码。我认为您可能对包含两次的标头有所了解,但我遇到的主要问题是 Byte[] rgbKeyData 的值没有被放入字节数组 arr 中。

【问题讨论】:

    标签: c# pinvoke cryptoapi


    【解决方案1】:

    Here 是一个结构/导入列表,看起来很有希望。不过还没有自己测试过。

    编辑:
    当您计算 blob 的大小时:您实际上是在计算标题两次吗?此外,您是如何得出 KEYBLOB 结构的声明的?

    【讨论】:

    • 那是我从中获得方法签名的地方,但这对结构没有帮助,我认为我编组错误。还是谢谢
    【解决方案2】:

    另一方面,你为什么还要在这里为所有这些 P/Invoke 东西烦恼? .NET Framework 具有内置类来为您完成所有这些工作。

    假设您使用的是 RSA 加密,RSACryptoServiceProvider 类提供了一个 ImportParameters 方法,该方法接受一个 RSAParameters 对象。
    干净,简单,正确的方法。

    你有什么理由不能用这个吗?

    【讨论】:

    • RSACryptoServiceProvider 是在 .NET 3.5 中引入的,我们被困在 .NET 2.0 :(
    • 根本不存在 - 绝对存在于 2.0 中,很确定它从 1.0/1.1 开始就存在 :-)。再次检查 - 它应该在 System.Security.Cryptography 中。您如何进行其余的加密,是否全部通过 P/Invoke...?
    • 是的,我所有的 p/invokes 都在这个之外工作。我尝试了 RijdaelManaged(sp?) 但我无法使用 Win32 Crypto API 对其进行解密。在所有条件相同(密钥、盐和 IV)的情况下,尝试解密密文失败。
    • 好吧,这似乎是一个单独的问题——我建议你在上面发布你的代码,没有理由它不应该工作。但是你真的应该使用 .NET 类来满足你所有的加密需求——包装 CryptoAPI 并不是一个好主意。正如我所说,它在 2.0 中都存在(甚至 RSA)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 2011-06-15
    相关资源
    最近更新 更多