Невозможно экспортировать 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.

Другие вопросы по тегам