Невозможно экспортировать PrivateKey перед импортом с использованием RSACng и RsaParameter
Следующий модульный тест экспортирует приватный ключ и сохраняет его в байтовых массивах с использованием экземпляра rsa, затем шифрует сообщение "hi", все в порядке, но проблема возникает, когда он создает экземпляр rsa2 и импортирует предыдущий приватный ключ в RSAParameter, после чего сообщение может быть дешифрованным после импорта privatekey, но он выдает исключение при попытке экспортировать privatekey из rsa2.
Скажите, пожалуйста, почему он не может извлечь импортированный закрытый ключ?
[TestMethod]
public void TestRsa()
{
var rsa = new RSACng(2048);
///Export private key to arrays
var rsaParam = rsa.ExportParameters(true);
byte[] yQ = new byte[rsaParam.Q.Length];
byte[] yP = new byte[rsaParam.P.Length];
byte[] yInverseQ = new byte[rsaParam.InverseQ.Length];
byte[] yDP = new byte[rsaParam.DP.Length];
byte[] yDQ = new byte[rsaParam.DQ.Length];
//Public Part Key
byte[] yPm = new byte[rsaParam.Modulus.Length];
byte[] yPe = new byte[rsaParam.Exponent.Length];
byte[] yD = new byte[rsaParam.D.Length];
rsaParam.Q.CopyTo(yQ, 0);
rsaParam.P.CopyTo(yP, 0);
rsaParam.InverseQ.CopyTo(yInverseQ, 0);
rsaParam.DP.CopyTo(yDP, 0);
rsaParam.DQ.CopyTo(yDQ, 0);
rsaParam.Modulus.CopyTo(yPm, 0);
rsaParam.Exponent.CopyTo(yPe, 0);
rsaParam.D.CopyTo(yD, 0);
var encrypt = rsa.Encrypt(Encoding.UTF8.GetBytes("hi"), RSAEncryptionPadding.Pkcs1);
///Importing private key in another instance of RSACng
var rsa2 = new RSACng(2048);
RSAParameters rsaParameters = new RSAParameters()
{
Q = yQ,
P = yP,
InverseQ = yInverseQ,
DP = yDP,
D = yD,
DQ = yDQ,
Exponent = yPe,
Modulus = yPm
};
rsa2.ImportParameters(rsaParameters);
var decryptData = rsa2.Decrypt(encrypt, RSAEncryptionPadding.Pkcs1);
Assert.AreEqual(Encoding.UTF8.GetString(decryptData), "hi");
rsa2.ExportParameters(true);///How can I prevent exception here
}
Спасибо всем!
1 ответ
В.NET Core объект RSACng должен находиться в состоянии экспорта при использовании ImportParameters, как и в.NET Framework 4.7.2.
Вы можете перевести в экспортируемое состояние, если измените политику экспорта, прежде чем использовать ключ (пытаясь вызвать Export или выполнить операцию sign / decrypt / encrypt / verify). Например, это работает:
using (RSA rsa1 = new RSACng(2048))
using (RSACng rsa2 = new RSACng())
{
rsa2.ImportParameters(rsa1.ExportParameters(true));
rsa2.Key.SetProperty(
new CngProperty(
"Export Policy",
BitConverter.GetBytes((int)CngExportPolicies.AllowPlaintextExport),
CngPropertyOptions.Persist));
RSAParameters params2 = rsa2.ExportParameters(true);
Console.WriteLine(params2.D.Length);
}
С использованием NCRYPT_EXPORT_POLICY_PROPERTY
описано по адресу https://msdn.microsoft.com/en-us/library/windows/desktop/aa376242(v=vs.85).aspx.