CLIENT_KEY_EXCHANGEがとんできた場所でencrypted_pre_master_secretをRSA解凍してpre_master_secretを取得します。
RSA秘密鍵(PrivateKey)はkey.derのバイナリデータそのままです。
pre_master_secretから各種キーを取得します。
MSのCryptApiを使用。RSA 2048bitでも動作します。



server_secret_key_: key.der

IByte pre_master_secret = Crypt::RsaDecrypt( encrypted_pre_master_secret, server_secret_key_ );

/////////////////////////////////////////////////////////////////////////////////////////////////////

IByte ByteArraySwap( const IByte& src )
{
int len = src.Length();
IByte r(0,len);

byte* dst = r.Get();
byte* psrc = src.Get();
for(int i = 0; i < len; i++)
*dst++ = psrc[len-i-1];

return r;
}

// static function
IByte Crypt::RsaDecrypt( const IByte& EncryptedData, IByte& PrivateKey )
{
HCRYPTKEY hPrivateKey = NULL;
HCRYPTPROV hProv = NULL;

BOOL bl = CryptAcquireContext(&hProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
_ASSERT(bl);

byte* key = PrivateKey.Get();
DWORD key_len = PrivateKey.Length();

DWORD cbKeyBlob;


bl = CryptDecodeObjectEx(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, key, key_len, 0, NULL, NULL, &cbKeyBlob))
_ASSERT(bl);


IByte KeyBlob(0, cbKeyBlob);

bl = CryptDecodeObjectEx(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, key, key_len, 0, NULL, KeyBlob.Get(), &cbKeyBlob))
_ASSERT(bl);

bl = CryptImportKey(hProv, KeyBlob.Get(), KeyBlob.Length(), 0, CRYPT_OAEP, &hPrivateKey);
_ASSERT(bl);

IByte r = ByteArraySwap( EncryptedData ); // big edian->little edian

DWORD dwSize = r.Length();

bl = CryptDecrypt(hPrivateKey, 0, TRUE, 0, r.Get(), &dwSize);
_ASSERT(bl);

if ( hPrivateKey ) CryptDestroyKey(hPrivateKey);
if ( hProv ) CryptReleaseContext(hProv, 0);

IByte DecryptedData( r.Get(), dwSize);
return DecryptedData;
}