У меня есть неуправляемое приложение, которое генерирует ключ шифрования RC4 с использованием Crypto API. Это неуправляемое приложение шифрует некоторые данные с помощью этого ключа RC4. Существует также неуправляемое приложение на стороне клиента, которое использует этот ключ RC4 для расшифровки информации.
Однако для этого клиентского приложения мы отправляем сеансовый ключ -> ключ RC4, зашифрованный с использованием открытого ключа RSA, сгенерированного на стороне клиента (SIMPLEBLOB). Раньше генерация зашифрованного ключа сеанса выполнялась с использованием неуправляемого кода, но теперь его необходимо преобразовать в C #, поскольку существует требование для запуска этого кода из веб-приложения с частичным доверием.
Ключ генерируется с помощью
CryptGenKey(hProv, CALG_RC4, KEY_LENGTH | CRYPT_EXPORTABLE, &hKey);
Экспортируется в файловую систему с помощью
CryptExportKey(hKey, 0, OPAQUEKEYBLOB, 0, lpBuffer, &nSize);
(обратите внимание, я смог экспортировать простой текстовый ключ, используя эту статью
http://www.codeproject.com/KB/security/plaintextsessionkey.aspx)
Открытый ключ клиента создается с использованием
CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKeyPair);
Открытый ключ клиента экспортируется с использованием
CryptExportKey(hKeyPair, 0, PUBLICKEYBLOB, 0, lpData, &nSize);
Ключ сеанса создается на стороне сервера с использованием
открытый ключ клиента импортируется с использованием
CryptImportKey (hProv, lpData, nSize, NULL, 0 и hPublicKey
Ключ сеанса генерируется путем шифрования RC4 с использованием открытого ключа клиента для генерации формата SIMPLEBLOB
CryptExportKey (hKey, hPublicKey, SIMPLEBLOB, 0, lpData, & nSize);
Теперь мое требование состоит в том, чтобы описанные выше шаги (шаги 1 и 2) были в управляемой версии, и вот что я делаю:
// Прочитать данные ключа в виде простого текста, которые были извлечены с использованием статьи проекта кода
byte [] keyMaterial = File.ReadAllBytes (@ "C: \ keyMaterial.txt");
// Импортировать открытый ключ клиента
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "Container Name";
cspParams.KeyNumber = (int)KeyNumber.Exchange;
cspParams.ProviderType = 1;
cspParams.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider rsaClient = new RSACryptoServiceProvider(cspParams);
rsaClient.ImportCspBlob(File.ReadAllBytes(@"C:\client.key"));
//Generate a SIMPLEBLOB session key
byte[] session = GetRC4SessionBlobFromKey(keyMaterial, rsaClient);
//Encrypt a key using public key and write it in a SIMPLEBLOB format
public byte[] GetRC4SessionBlobFromKey(byte[] keyData, RSACryptoServiceProvider publicKey)
{
using(MemoryStream ms = new MemoryStream())
using(BinaryWriter w = new BinaryWriter(ms))
{
w.Write((byte) 0x01); // SIMPLEBLOB
w.Write((byte) 0x02); // Version 2
w.Write((byte) 0x00); // Reserved
w.Write((byte) 0x00); // Reserved
w.Write(0x00006801); // ALG_ID = RC4 for the encrypted key.
w.Write(0x0000a400); // CALG_RSA_KEYX
w.Write(publicKey.Encrypt(keyData, false));
w.Flush();
return ms.ToArray();
}
}
Это генерирует тот же размер данных, что и его неуправляемая версия, но не генерирует правильный ключ сеанса SIMPLEBLOB, как при выполнении шага 1 и 2 неуправляемой версии. Что я делаю не так в этом коде?