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

Viewed 4828

I got this exception:

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

calling this method:

GoogleCredential cred = GoogleCredential.FromFile(path);

Full exception:

Unable to cast object of type 'RSACng' to type 'System.Security.Cryptography.RSACryptoServiceProvider'
   at Google.Apis.Auth.OAuth2.ServiceAccountCredential.Initializer.FromPrivateKey(String privateKey) in C:\Apiary\2019-09-11.10-11-15\Src\Support\Google.Apis.Auth\OAuth2\ServiceAccountCredential.cs:line 110
   at Google.Apis.Auth.OAuth2.DefaultCredentialProvider.CreateServiceAccountCredentialFromParameters(JsonCredentialParameters credentialParameters) in C:\Apiary\2019-09-11.10-11-15\Src\Support\Google.Apis.Auth\OAuth2\DefaultCredentialProvider.cs:line 243
   at Google.Apis.Auth.OAuth2.DefaultCredentialProvider.CreateDefaultCredentialFromParameters(JsonCredentialParameters credentialParameters) in C:\Apiary\2019-09-11.10-11-15\Src\Support\Google.Apis.Auth\OAuth2\DefaultCredentialProvider.cs:line 197
   at Google.Apis.Auth.OAuth2.GoogleCredential.FromFile(String path) in C:\Apiary\2019-09-11.10-11-15\Src\Support\Google.Apis.Auth\OAuth2\GoogleCredential.cs:line 114
   at ServerUtil.GCloudReporter..ctor(String version, String deployEnv)  

Using .NET Framework 4.5.1

Google apis libs version 1.41.1

4 Answers

I was getting exactly the same exception.

In my case I was using Sustainsys.Saml2.AspNetCore2 version (2.8.0) nuget package.

I've updated to 2.9.0 and delete all cookies related to authentication.

It solved my problem.

Problem was that app was running in .NET Core environment, but this specific code was in project setup for .NET Framework. Moving code to project with .NET Core setup fix problem.

In my case, I had this error when wanted to use my notification service from the service layer into my .NetCore project.

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

I only added "FirebaseAdmin" package to my .NetCore project using package manager.

it was confusing for me because I did not get this error on my .Net Framework project which does not need this package.

pretty silly mistake but I hope this saves others valuable time

.NET core Step1: insall System.Security.Cryptography.Cng from nuget pkg Step2:create a class "X509Certificate2Signature"

    using iTextSharp.text.pdf.security;
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace DigiSignNETCORE
{
    public class X509Certificate2Signature : IExternalSignature
    {
        private String hashAlgorithm;
        private String encryptionAlgorithm;
        private X509Certificate2 certificate;

        public X509Certificate2Signature(X509Certificate2 certificate, String hashAlgorithm)
        {
            if (!certificate.HasPrivateKey)
                throw new ArgumentException("No private key.");
            this.certificate = certificate;
            this.hashAlgorithm = DigestAlgorithms.GetDigest(DigestAlgorithms.GetAllowedDigests(hashAlgorithm));
            if (certificate.PrivateKey is RSACryptoServiceProvider)
                encryptionAlgorithm = "RSA";
            else if (certificate.PrivateKey is DSACryptoServiceProvider)
                encryptionAlgorithm = "DSA";
            
            else if (certificate.PrivateKey is System.Security.Cryptography.RSACng)
                encryptionAlgorithm = "RSA";
        }

        public virtual byte[] Sign(byte[] message)
        {
            if (certificate.PrivateKey is RSACryptoServiceProvider)
            {
                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certificate.PrivateKey;
                return rsa.SignData(message, hashAlgorithm);
            }
           else if (certificate.PrivateKey is System.Security.Cryptography.RSACng)
            {
                System.Security.Cryptography.RSACng rSACng = (System.Security.Cryptography.RSACng)certificate.PrivateKey;
                return rSACng.SignData(message,HashAlgorithmName.SHA1,RSASignaturePadding.Pkcs1);
            }

            else
            {
                DSACryptoServiceProvider dsa = (DSACryptoServiceProvider)certificate.PrivateKey;
                return dsa.SignData(message);
            }
        }

        public virtual String GetHashAlgorithm()
        {
            return hashAlgorithm;
        }

        public virtual String GetEncryptionAlgorithm()
        {
            return encryptionAlgorithm;
        }
    }
}

step 3 : in this line IExternalSignature externalSignature = new X509Certificate2Signature(cert, "SHA1"); point the class "X509Certificate2Signature" which you created recenlty.

Related