Расшифровка с использованием импортированного ключа с одного сервера не работает на другом сервере

У меня есть два сервера Windows 2008 R2, Сервер 1 и Сервер 2. Я сгенерировал пару ключей RSA на Сервере 1 под учетной записью Windows 1, используя:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pc "MyKeys" -exp
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -px "MyKeys" keys.xml -pri

Я скопировал keys.xml на Сервер 2. На сервере 2 под учетной записью Windows 2 я запустил:

    C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pi "MyKeys" keys.xml

Я использую следующий код C# для шифрования и дешифрования:

private static RSACryptoServiceProvider CreateRsaCypher(string containerName)
{
  // Create the CspParameters object and set the key container 
  // name used to store the RSA key pair.
  CspParameters cp = new CspParameters();
  cp.KeyContainerName = containerName;

  // Create a new instance of RSACryptoServiceProvider that accesses
  // the key container MyKeyContainerName.
  return new RSACryptoServiceProvider(cp);
}

public static string AsymmetricEncrypt(byte[] data, string containerName)
{
  RSACryptoServiceProvider cipher = CreateRsaCypher(containerName);
  byte[] cipherText = cipher.Encrypt(data, false);
  return Convert.ToBase64String(cipherText);
}

public static string AsymmetricEncrypt(string str, string containerName )
{
  return AsymmetricEncrypt(Encoding.UTF8.GetBytes(str), containerName);
}

public static byte[] AsymmetricDecrypt(string data, string containerName)
{
  RSACryptoServiceProvider cipher = CreateRsaCypher(containerName);
  return cipher.Decrypt(Convert.FromBase64String(data), false);
}

public static string AsymmetricDecryptToString(string data, string containerName)
{
  return Encoding.UTF8.GetString(AsymmetricDecrypt(data, containerName));
}

Теперь, когда я зашифровываю строку на сервере 1, используя тот же контейнер под учетной записью 1, если я пытаюсь расшифровать ее на сервере 2 под учетной записью 2, я получаю:

Unhandled Exception: System.Security.Cryptography.CryptographicException: Bad Data.

   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle pKeyContext, Byte[] pbEncryptedKey, Int32 cbEncryptedKey, Boolean fOAEP, ObjectHandleOnStack ohRetDecryptedKey)
   at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)

Приложение, которое я шифрую / дешифрую, является консольным приложением C#.

Я заметил, что Сервер 1 и Сервер 2 не имеют одинаковую версию aspnet_regiis.exe, один из них:

Microsoft (R) ASP.NET RegIIS version 4.0.30319.0

другой это:

Microsoft (R) ASP.NET RegIIS version 4.0.30319.18408

Является ли мое ожидание того, что я могу расшифровать текст, зашифрованный на Сервере 1, с помощью того же ключа на Сервере 2 (то есть пары ключей, которая была экспортирована на Сервере 1 и импортирована на Сервере 2), неверно? Изменяет ли Windows как-то открытый / закрытый ключи при импорте?

Заранее спасибо!

Просто обновление. Основываясь на других тестах, я заметил, что шифрование одной и той же строки одним и тем же контейнером RSA под разными учетными записями Windows приводит к различным строкам шифрования, что в некотором смысле имеет смысл. Это объясняет поведение, которое я вижу.

1 ответ

Хорошо, у меня это работает согласованно между двумя учетными записями, и ключом было установить флаг UseMachineKeyStore.

private static RSACryptoServiceProvider CreateRsaCypher(string containerName = DefaultContainerName)
{
  // Create the CspParameters object and set the key container 
  // name used to store the RSA key pair.
  CspParameters cp = new CspParameters();
  cp.KeyContainerName = containerName;
  cp.Flags = CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore;
  // Create a new instance of RSACryptoServiceProvider that accesses
  // the key container MyKeyContainerName.
  return new RSACryptoServiceProvider(cp);
}
Другие вопросы по тегам