【问题标题】:Trying to perform a Diffie Hellman Key exchange, using Win32 API in C#尝试使用 C# 中的 Win32 API 执行 Diffie Hellman 密钥交换
【发布时间】:2010-07-30 10:26:49
【问题描述】:

我正在尝试构建一些可以在旧 CAPI 或新的基于 CNG 的 Diffie-Hellman 算法之间切换的代码。

(尽管有文档,但新的基于 ECC 的 DH 算法作为 CNG 的一部分在 Windows XP 上不受支持)。

反正我已经开始暴露Win32 CAPI了,如下:

public static class CAPI
{
    private static int ALG_CLASS_KEY_EXCHANGE = 5 << 13;
    private static int ALG_TYPE_DH = 5 << 9;
    private static int ALG_SID_DH_EPHEM = 2;

    public static int CALG_DH_EPHEM = (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_EPHEM);
    public static uint CRYPT_VERIFYCONTEXT = 0xF0000000;
    public static uint CRYPT_SILENT = 0x00000040;
    public static uint PROV_DSS_DH = 13;
    public static uint CRYPT_EXPORTABLE = 0x00000001;
    public static uint CRYPT_PREGEN = 0x00000040;
    public static uint KEY_SIZE = 0x00000400;

    public static string MS_ENH_DSS_DH_PROV = "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider";

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptAcquireContext(ref IntPtr hProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool CryptGenKey(IntPtr hProv, int Algid, uint dwFlags, ref IntPtr phKey);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool CryptDestroyKey(IntPtr key);
}

我已经开始在此基础上构建一个 .NET DH 类:

public sealed class CAPIDiffieHellman : IDisposable
{
    private IntPtr _publicKeyPointer = new IntPtr();
    private IntPtr _hProv = new IntPtr();
    private uint _contextFlags = CAPI.CRYPT_VERIFYCONTEXT | CAPI.CRYPT_SILENT;
    private uint _keyGenerationFlags = CAPI.CRYPT_EXPORTABLE | CAPI.CRYPT_PREGEN;

    public CAPIDiffieHellman()
    {
        if (!CAPI.CryptAcquireContext(
            ref this._hProv,
            null,
            CAPI.MS_ENH_DSS_DH_PROV,
            CAPI.PROV_DSS_DH,
            this._contextFlags))
        {
            throw new ApplicationException(string.Format("Unable to acquire cryptographic context. Error Code: {0}", Marshal.GetLastWin32Error()));
        }
    }

    public byte[] GeneratePublicKey()
    {
        if (!CAPI.CryptGenKey(this._hProv, CAPI.CALG_DH_EPHEM, this._keyGenerationFlags, ref this._publicKeyPointer))
        {
            throw new ApplicationException(string.Format("Unable to generate cryptographic key. Error Code: {0}", Marshal.GetLastWin32Error()));
        }

        var publicKey = new byte[128];
        Marshal.Copy(this._publicKeyPointer, publicKey, 0, publicKey.Length);

        return publicKey;
    }

    public byte[] DerivePrivateKey(byte[] publicKey)
    {
        return null;
    }

    public void Dispose()
    {
        CAPI.CryptReleaseContext(this._hProv, 0);
        CAPI.CryptDestroyKey(this._publicKeyPointer);
    }
}

我正在使用这个documentation

但是,我意识到我不确定我需要遵循什么流程;我所说的“公钥”可能不是!

因此,非常感谢提供有关如何使用 CAPI 执行 DH 密钥交换的分步指南!

谢谢。

【问题讨论】:

    标签: c# interop cryptography cryptoapi


    【解决方案1】:

    使用此方法通过传递对应的 isPublicKey 值来获取公钥或私钥:

    public static bool ExportCryptKey(IntPtr cryptKey, out byte[] outData, ref uint outDataSize, bool isPublicKey)
            {
                uint keyType = isPublicKey ? 0x6u : 0x7u;
                outData = null;
                if (!CryptExportKey(cryptKey, IntPtr.Zero, keyType, 0, null, ref outDataSize))
                {
                    var err = Marshal.GetLastWin32Error();
                    Debug.Print(new Win32Exception(err).Message);
                    return false;
                }
    
                outData = new byte[outDataSize];
    
                if (!CryptExportKey(cryptKey, IntPtr.Zero, keyType, 0, outData, ref outDataSize))
                    return false;
    
                return true;
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2014-05-13
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      相关资源
      最近更新 更多