<p>There's an MSDN article <a href="http://msdn.microsoft.com/en-us/library/aa919730.aspx" rel="nofollow noreferrer">here</a>, but I'm not getting very far:</p>

<pre><code>p = 139;
g = 5;

CRYPT_DATA_BLOB pblob;
pblob.cbData = sizeof( ULONG );
pblob.pbData = ( LPBYTE ) &amp;p;

CRYPT_DATA_BLOB gblob;
gblob.cbData = sizeof( ULONG );
gblob.pbData = ( LPBYTE ) &amp;g;

HCRYPTKEY hKey;
if ( ::CryptGenKey( m_hCryptoProvider, CALG_DH_SF,
                    CRYPT_PREGEN, &amp;hKey ) )
{
    ::CryptSetKeyParam( hKey, KP_P, ( LPBYTE ) &amp;pblob, 0 );
</code></pre>

<p>Fails here with <code>NTE_BAD_DATA</code>.  I'm using <code>MS_DEF_DSS_DH_PROV</code>.   What gives?</p>

[{'answer_id': 78156, 'author': 'Mike Dimmick', 'author_id': 6970, 'author_profile': 'https://Stackoverflow.com/users/6970', 'pm_score': 1, 'selected': False, 'text': '<p>It looks to me that <code>KP_P</code>, <code>KP_G</code>, <code>KP_Q</code> are for DSS keys (Digital Signature Standard?). For Diffie-Hellman it looks like you\'re supposed to use <code>KP_PUB_PARAMS</code> and pass a <code>DATA_BLOB</code> that points to a <code>DHPUBKEY_VER3</code> structure.</p>\n\n<p>Note that the article you\'re pointing to is from the Windows Mobile/Windows CE SDK. It wouldn\'t be the first time that CE worked differently from the desktop/server.</p>\n\n<p>EDIT: CE does not implement <code>KP_PUB_PARAMS</code>. To use this structure on the desktop, see <a href="http://msdn.microsoft.com/en-us/library/aa381974(VS.85).aspx" rel="nofollow noreferrer">Diffie-Hellman Version 3 Public Key BLOBs</a>.</p>\n'}, {'answer_id': 78537, 'author': 'Mike Dimmick', 'author_id': 6970, 'author_profile': 'https://Stackoverflow.com/users/6970', 'pm_score': 3, 'selected': True, 'text': '<p>It may be that it just doesn\'t like the very short keys you\'re using.</p>\n\n<p>I found <a href="http://msdn.microsoft.com/en-us/library/aa381969.aspx" rel="nofollow noreferrer">the desktop version of that article</a> which may help, as it has a full example.</p>\n\n<p>EDIT:</p>\n\n<p>The OP realised from the example that you have to tell CryptGenKey how long the keys are, which you do by setting the top 16-bits of the flags to the number of bits you want to use. If you leave this as 0, you get the default key length. This <em>is</em> documented in the <strong>Remarks</strong> section of the device documentation, and with the <em>dwFlags</em> parameter in the <a href="http://msdn.microsoft.com/en-us/library/aa379941(VS.85).aspx" rel="nofollow noreferrer">desktop documentation</a>. </p>\n\n<p>For the Diffie-Hellman key-exchange algorithm, the Base provider defaults to 512-bit keys and the Enhanced provider (which is the default) defaults to 1024-bit keys, on Windows XP and later. There doesn\'t seem to be any documentation for the default lengths on CE.</p>\n\n<p>The code should therefore be:</p>\n\n<pre><code>BYTE p[64] = { 139 }; // little-endian, all other bytes set to 0\nBYTE g[64] = { 5 };\n\nCRYPT_DATA_BLOB pblob;\npblob.cbData = sizeof( p);\npblob.pbData = p;\n\nCRYPT_DATA_BLOB gblob;\ngblob.cbData = sizeof( g );\ngblob.pbData = g;\n\nHCRYPTKEY hKey;\nif ( ::CryptGenKey( m_hCryptoProvider, CALG_DH_SF,\n                    ( 512 &lt;&lt; 16 ) | CRYPT_PREGEN, &amp;hKey ) )\n{\n    ::CryptSetKeyParam( hKey, KP_P, ( LPBYTE ) &amp;pblob, 0 );\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/76581', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/-1/']