0

the next unit test export a privatekey and save it in bytes arrays using the rsa instance then encrypt the "hi" message, all is fine here, but the problem occur when It make rsa2 instance and import the previous privatekey in RSAParameter, then message can be decrypt after import privatekey, but It throw exception when you try to export privatekey of rsa2.

Please could you tell me why It can't extract Imported Private key

    [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
  }

Thanks all!

Zaha
  • 846
  • 10
  • 21
  • What if you use rsa2.ImportParameters(rsaParam)? – Jeroen Heier Feb 06 '18 at 05:02
  • I can't because my private key is stored in array of bytes, so it does not have the rsaParam object in real life, I summarized to make it more clearer – Zaha Feb 06 '18 at 12:13
  • Anyway when rsaParam is assigned It throw exception too. – Zaha Feb 06 '18 at 14:42
  • I believe this is fixed in net472. https://blogs.msdn.microsoft.com/dotnet/2018/02/05/announcing-net-framework-4-7-2-early-access-build-3052/ – bartonjs Feb 06 '18 at 16:06

1 Answers1

1

In .NET Core the RSACng object should be in an exportable state when you use ImportParameters, and it should be the case in .NET Framework 4.7.2 as well.

You can put into an exportable state as long as you change the export policy before using the key (by trying to call Export or doing a sign/decrypt/encrypt/verify operation). For example, this works:

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);
}

Using the NCRYPT_EXPORT_POLICY_PROPERTY described at https://msdn.microsoft.com/en-us/library/windows/desktop/aa376242(v=vs.85).aspx.

bartonjs
  • 30,352
  • 2
  • 71
  • 111