none
Cryptography: net standard 2.0 class library, net core 2.2 app, cannot use keys from X509certificate RRS feed

  • Question

  • The problem:

    Using keys contained in an X509 certificate for encryption, implemented in a .Net Standard 2.0 class library, doesn't work if that class library is used by a .Net Core 2.2 application. Or at least *I* cannot get it to work, which is the same thing for me.

    I'm not trying to re-invent SSL, what we want to do is encrypt data in a file that is to be sent to us, using anything from 'usb stick by sneaker mail' on up. They use our public key to encrypt, and we decrypt using our private key.

    I condensed the problem into a test solution with 3 projects which I can make available, if anyone would want it:

    • Net Standard 2.0 class library containing the cryptographic functions
    • Windows Forms app, framework 4.7.2: can use the crypto functions, no problem.
    • Net Core 2.2 web app: cannot use the crypto functions.

    What happens?

    The Net Std DLL reads an X509 certificate with the intent to use its keys to asymetrically encrypt a file. It contains simple Encrypt en Decrypt functions, these automatically use the private key when is available (i.e. running here), otherwise the public key if it is running at a client.

    Simplified code:

    	X509Store my = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    	my.Open(OpenFlags.ReadOnly);
    	X509Certificate2Collection collection = my.Certificates.Find(X509FindType.FindBySubjectName, CertificateName, true);
    
    	_certificate = collection[0];
    
    // somewhere else
    
    	RSACryptoServiceProvider csp = (RSACryptoServiceProvider)_certificate.PrivateKey;
    
    // or
    
    	RSACryptoServiceProvider csp = (RSACryptoServiceProvider)_certificate.PublicKey.Key;
    
    // Also tried with
    
    	RSACryptoServiceProvider csp = (RSACryptoServiceProvider)_certificate.GetRSAPrivateKey();
    	RSACryptoServiceProvider csp = (RSACryptoServiceProvider)_certificate.GetRSAPublicKey();


    This works fine in the Windows Forms application under 'Classic' framework 4.7.2.

    But when the same library is called by the Net Core web app, running in IIS Express with a Core 2.2 runtime, on the same machine, using the same certificate, it balks out. The returned RSA key is a RSACng class.

    InvalidCastException: Unable to cast object of type 'System.Security.Cryptography.RSACng' to type 'System.Security.Cryptography.RSACryptoServiceProvider'.

    But .Net Standard doesn't *know* RSACng, so I can't even try to convert or re-create it from code.



    • Edited by lucvdv Monday, August 19, 2019 11:34 AM
    Monday, August 19, 2019 11:25 AM

Answers

  • As usual, after googling and dabbling for a few days, and finally giving up and posting a question, I found the solution less than an hour later.

    Don't try find a way to magic that RSACng into an RSACryptoServiceProvider.
    Instead, replace (RSACryptoServiceProvider) by (RSA), change the boolean padding argument in the encrypt/decrypt calls to a value from enum RSAEncryptionPadding, and it works.

    -- edit --

    And finally, I had to pick RSAEncryptionPadding.OaepSHA1 instead of RSAEncryptionPadding.OaepSHA256, or it would work only in the the .NetCore implementation, and fail with "Specified padding mode is not valid for this algorithm" in Windows forms. 



    • Marked as answer by lucvdv Monday, August 19, 2019 12:14 PM
    • Edited by lucvdv Monday, August 19, 2019 12:19 PM
    Monday, August 19, 2019 12:11 PM

All replies

  • As usual, after googling and dabbling for a few days, and finally giving up and posting a question, I found the solution less than an hour later.

    Don't try find a way to magic that RSACng into an RSACryptoServiceProvider.
    Instead, replace (RSACryptoServiceProvider) by (RSA), change the boolean padding argument in the encrypt/decrypt calls to a value from enum RSAEncryptionPadding, and it works.

    -- edit --

    And finally, I had to pick RSAEncryptionPadding.OaepSHA1 instead of RSAEncryptionPadding.OaepSHA256, or it would work only in the the .NetCore implementation, and fail with "Specified padding mode is not valid for this algorithm" in Windows forms. 



    • Marked as answer by lucvdv Monday, August 19, 2019 12:14 PM
    • Edited by lucvdv Monday, August 19, 2019 12:19 PM
    Monday, August 19, 2019 12:11 PM
  • I have tried with same code as mention in your answer but not getting specific output . i think padding is not work for me as expected encryption while in my old code its working correctly  .

    Can you please help me regarding this  .

    Saturday, March 21, 2020 6:02 AM