在 C# 中使用 PFX 文件加密字符串

Encrypting string using a PFX-File in C#

我想使用 PFX 文件加密我的字符串。然后将加密后的字符串写入数据库。 PFX 文件的密码安全地存储在 app.config 中并进行了加密。总是在执行该方法时抛出 System.NullReferenceException,但我不知道为什么。我看着我的变量,文件的密码被正确解密。这是我的源代码。

public string EncryptString(string text, string certificatePath, string password)
    {
        byte[] data = Encoding.UTF8.GetBytes(text);
        X509Certificate2Collection collection = new X509Certificate2Collection();
        collection.Import(certificatePath, password, X509KeyStorageFlags.PersistKeySet);
        X509Certificate2 certificate = collection[0];
        RSACryptoServiceProvider publickey = certificate.PublicKey.Key as RSACryptoServiceProvider;
        byte[] encrypted = publickey.Decrypt(data, false);

        return Convert.ToBase64String(encrypted);
    }

调试后 Visual Studio 说“publickey = null”

PFX 作为 Base64:

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

(我用 XCA 创建了我的证书) 密码:test123

有人可以帮助我吗?

您不能只使用 pfx 加密数据,您需要指定一种格式。

Windows uses .pfx for a PKCS #12 file. This file can contain a variety of cryptographic information, including certificates, certificate chains, root authority certificates, and private keys. Its contents can be cryptographically protected (with passwords) to keep private keys private and preserve the integrity of root certificates.

What is the difference between a cer, pvk, and pfx file?

有了 EnvelopedCms,您就有了一种易于使用并使用 pfx 文件的格式,有关详细信息,请参阅加密消息语法 https://www.rfc-editor.org/rfc/rfc5652

如果您想保护敏感数据,您应该让专家审查您的实施!

代码

一些学生出于 学习目的https://github.com/haevg-rz/LearnToCode/blob/master/Examples/EncryptionDemo/EncryptionDemo.Sample/CryptographicMessageSyntax.cs

我稍微更改了代码,因此它更适合您的代码。

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Pkcs;
using System.Text;
using System.IO;
using System.Security;

namespace PfxTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello to PfxTest!");
            File.WriteAllBytes("test.pfx", Convert.FromBase64String(pfxBase64));
            
            var r = EncryptString("Hello", "test.pfx","test123");
            Console.WriteLine(r);
        }

        static string pfxBase64 = "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";

        static public string EncryptString(string text, string certificatePath, string password)
        {
            byte[] data = Encoding.UTF8.GetBytes(text);
            CmsRecipientCollection collection = new CmsRecipientCollection();
             var secureString = new SecureString();
            foreach (var item in password) secureString.AppendChar(item);
            var certificate = new X509Certificate2(File.ReadAllBytes(certificatePath),secureString);
            collection.Add(new CmsRecipient(certificate,RSAEncryptionPadding.OaepSHA512));
            
            var envelopedCms = new EnvelopedCms(new ContentInfo(data));
            if (envelopedCms.ContentEncryptionAlgorithm.Oid.FriendlyName != "aes256")
                // After .NET Core 3 aes256 is the standard ContentEncryptionAlgorithm, before it was 3des.
                throw new Exception("Only aes256 is allowed.");

            envelopedCms.Encrypt(collection);
            var encrypted = envelopedCms.Encode();

            return Convert.ToBase64String(encrypted);
        }
    }
}

输出

PS C:\DEV\PfxTest> dotnet run
Hello to PfxTest!
MIICBgYJKoZIhvcNAQcDoIIB9zCCAfMCAQAxggGuMIIBqgIBADBjMFcxCzAJBgNVBAYTAkRFMRswGQYDVQQIDBJCYWRlbi1Xw7xydHRlbWJlcmcxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRlc3QxDTALBgNVBAMTBFRlc3QCCHmuh+2/frVqMDwGCSqGSIb3DQEBBzAvoA8wDQYJYIZIAWUDBAIDBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIDBQAEggEAfHlhUeK6xv7jPZzE6/VFFrAh6dnEMrxeOivkUWr5TtWiu4Bulmd7QuhEwSNXvzLUW8uBVxkqHCWwY4jIM4QX8deCEY29DrLNyFM7XWl8wzxM4VJlL6E20zCQskAh+zuXq1KqNV8blXX7D+VYBl8xobDA1Lwp8iBU+4haajq7L2/XTtQphYVQY+tHMBbNArqZAt9UiV1RQFy4rzY5vwRnaukousJEaw58OlfnuVbX9/30q1RCXGt+MMkkUV4H/273JPQ0z5MXNtiqRpJLjoQehvhyjeviaqk/6M+f4hXjF+sgIe2UCxpMS3yiQJNFY8Ahw7OcBaszaDzYh5vBrTHjNjA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBtJS1U3cF3DtpKH9JReigSgBCmbHnsRVXWmZVilQbGnBXj