2010-08-03 57 views
0

我正在尝试使用CryptoAPI(CAPI)执行Diffie Hellman密钥交换。我正在使用MSDN文档。调用CryptGetKeyParam时出现异常

 // Step 0) Acquire context 
     if (!CAPI.CryptAcquireContext(ref this._cryptographicProvider, null, null, CAPI.PROV_DSS_DH, CAPI.CRYPT_VERIFYCONTEXT)) 
      HandleWin32Error("Unable to acquire cryptographic context"); 

     // Setp 1) Generate private key 
     if (!CAPI.CryptGenKey(this._cryptographicProvider, CAPI.CALG_DH_EPHEM, DHKEYSIZE << 16 | CAPI.CRYPT_EXPORTABLE | CAPI.CRYPT_PREGEN, ref this._privateKeyPointer)) 
      HandleWin32Error("Unable to generate private cryptographic key"); 

     uint gSize = 0; 
     CAPI.CryptGetKeyParam(this._privateKeyPointer, CAPI.KP_G, null, ref gSize, (uint)0); 

     byte[] g = new byte[gSize]; 
     var res = CAPI.CryptGetKeyParam(this._privateKeyPointer, CAPI.KP_G, g, ref gSize, (uint)0); 

第一呼叫CryptGetKeyParam完美地工作,即它成功返回G的尺寸,如64

然后代码失败在最后一行,或者通过任何返回到克缓冲液(如与解析度=在该示例的情况下)为真,或当我使用下面的呼叫的AccessViolationException:

var res = CAPI.CryptGetKeyParam(this._privateKeyPointer, CAPI.KP_G, ref g, ref gSize, (uint)0); 

是的,我重载在P \调用方法:

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern bool CryptGetKeyParam(IntPtr hKey, uint dwParam, ref byte[] pbData, ref uint pdwDataLen, uint dwFlags); 

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern bool CryptGetKeyParam(IntPtr hKey, uint dwParam, byte[] pbData, ref uint pdwDataLen, uint dwFlags); 

对此有何想法/想法? *有趣的是,我设法让一个完整的Diffie Hellman密钥交换工作,即成功地同意两方之间的相同秘密(s1)。但是这与预先定义的P和G参数有关。我正在重新编写代码,因为有些东西似乎并不正确,因为每个密钥交换的派生秘密都是一样的,这意味着X是一致的。 (即Bob和Alice每次都在s1上达成一致!) - 在这里,我又一次遇到了CryptGetKeyParam的问题,因为在使用KP_KEYLEN时我无法确定会话密钥的大小。 *

回答

1

啊哈!

这是上下文标志和重载方法的组合......现在就可以了!

在P & G的不是预定义的,那么就不要设置CRYPT_PREGEN标志......而且,只有需要的两个重载方法之一(这个):

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern bool CryptGetKeyParam(IntPtr hKey, uint dwParam, byte[] pbData, ref uint pdwDataLen, uint dwFlags); 
相关问题