簡體   English   中英

X509Certificate2:使用私鑰解密時訪問被拒絕

[英]X509Certificate2: Access denined when decrypting with privatekey

我有以下代碼,用於(加密)解密密鑰,該密鑰又用於加密放置在客戶端標頭中的字符串,應用程序可能會緩存其中的一些字符串。 (它們包含敏感信息)。 在這種情況下,該應用程序是在IIS上運行的ASP .Net core 2.0。

使用公共密鑰的加密工作得很好,但是當我嘗試解密時會拋出異常。

    private string DecryptKey(string key)
    {
        if (this.Certificate == null || string.IsNullOrEmpty(key))
            throw new Exception("A x509 certificate and string for decryption must be provided");

        // Get the string as bytes
        var encryptedBytes = Convert.FromBase64String(key);

        if (!Certificate.HasPrivateKey)
            throw new Exception("x509 certificate does not contain a private key for decryption");

        using (var rsa = Certificate.GetRSAPrivateKey())
        {
            var result = rsa.Decrypt(encryptedBytes, RSAEncryptionPadding.OaepSHA512); // **Exception is thrown here**
            return ASCIIEncoding.ASCII.GetString(result);
        }
    }

    private string EncryptKey(string key)
    {
        if (this.Certificate == null || string.IsNullOrEmpty(key))
            throw new Exception("A x509 certificate and string for decryption must be provided");

        // Get the string as bytes
        var bytes = ASCIIEncoding.ASCII.GetBytes(key);

        if (!Certificate.HasPrivateKey)
            throw new Exception("x509 certificate does not contain a private key for decryption");

        using (var rsa = Certificate.GetRSAPrivateKey())
        {
            var result = rsa.Encrypt(bytes, RSAEncryptionPadding.OaepSHA512);
            return Convert.ToBase64String(result);
        }
    }

    /// <summary>
    /// Returns a X509Certificate2 with the given name
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    protected X509Certificate2 GetX509Certificate(string name)
    {
        // Get the certificate store for the current user.
        var store = new X509Store(StoreLocation.LocalMachine);

        try
        {
            store.Open(OpenFlags.ReadOnly);

            // Place all certificates in an X509Certificate2Collection object.
            var certCollection = store.Certificates;

            var currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
            var signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, name, false);

            if (signingCert.Count == 0)
                return null;

            return signingCert[0];
        }
        finally
        {
            store.Close();
        }
    }

異常: Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException:'訪問被拒絕'

這是堆棧:

        at System.Security.Cryptography.RSACng.EncryptOrDecrypt(SafeNCryptKeyHandle key, Byte[] input, AsymmetricPaddingMode paddingMode, Void* paddingInfo, EncryptOrDecryptAction encryptOrDecrypt)
        at System.Security.Cryptography.RSACng.EncryptOrDecrypt(Byte[] data, RSAEncryptionPadding padding, EncryptOrDecryptAction encryptOrDecrypt)
        at System.Security.Cryptography.RSACng.Decrypt(Byte[] data, RSAEncryptionPadding padding)
        at VmeApi.Extensions.KeyEncryptService.DecryptKey(String key) in C:\Users\kevom\Source\Repos\VME\VME Management\Management Core Api\Extensions\AppSettings\KeyEncryptService.cs:line 69
        at VmeApi.Extensions.KeyEncryptService..ctor(String certName, String encryptedKey) in C:\Users\kevom\Source\Repos\VME\VME Management\Management Core Api\Extensions\AppSettings\KeyEncryptService.cs:line 31
        at Management_Core_Api.Startup.ConfigureServices(IServiceCollection services) in C:\Users\kevom\Source\Repos\VME\VME Management\Management Core Api\Startup.cs:line 83

我嘗試使用mmc授予我的帳戶,IUser帳戶和網絡服務對證書的私鑰的完全訪問權限,然后重新啟動OS,但這無濟於事。

這可能有點長,所以我將其作為答案,因為作為注釋的格式可能不夠,

嘗試檢查是否可以使用以下代碼訪問私鑰

private static string FindKeyLocation(string keyFileName)
        {
            string firstLocation =
            Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
            string secondLocation = firstLocation + @"\Microsoft\Crypto\RSA\MachineKeys";
            string[] textArray1 = Directory.GetFiles(secondLocation, keyFileName);
            if (textArray1.Length > 0)
            {
                return secondLocation;
            }
            string thirdLocation =
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string forthLocation = thirdLocation + @"\Microsoft\Crypto\RSA\";
            textArray1 = Directory.GetDirectories(forthLocation);
            if (textArray1.Length > 0)
            {
                foreach (string fifthLocation in textArray1)
                {
                    textArray1 = Directory.GetFiles(fifthLocation, keyFileName);
                    if (textArray1.Length != 0)
                    {
                        return fifthLocation;
                    }
                }
            }
            return "Private key exists but is not accessible";
        }

您可以通過將證書fileName指定為來使用代碼

RSACryptoServiceProvider rsa = cert.PrivateKey as RSACryptoServiceProvider;

            if (rsa != null)
            {
                string keyfilepath =
                    FindKeyLocation(rsa.CspKeyContainerInfo.UniqueKeyContainerName);
            }

這段代碼也許可以闡明解密為什么不起作用的原因,將用戶添加到證書中的完整方法看起來像這樣

private static void AddAccessToCertificate(X509Certificate2 cert, string user)
        {
            RSACryptoServiceProvider rsa = cert.PrivateKey as RSACryptoServiceProvider;

            if (rsa != null)
            {
                string keyfilepath =
                    FindKeyLocation(rsa.CspKeyContainerInfo.UniqueKeyContainerName);

                FileInfo file = new FileInfo(keyfilepath + "\\" +
                    rsa.CspKeyContainerInfo.UniqueKeyContainerName);

                FileSecurity fs = file.GetAccessControl();

                NTAccount account = new NTAccount(user);
                fs.AddAccessRule(new FileSystemAccessRule(account,
                FileSystemRights.FullControl, AccessControlType.Allow));

                file.SetAccessControl(fs);
            }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM