X509证书2 构造函数参数字符串文件名类型



第一个参数中文件的格式(.pfx,.cer或其他东西)应该是什么?

public X509Certificate2(
string fileName,
SecureString password,
X509KeyStorageFlags keyStorageFlags
)

更多背景:

尝试使用以下函数获取证书时,我收到以下错误 -

功能:

public static X509Certificate2 AuthenticationCertificate(string AuthenticationCertificateAsBase64String, string AuthenticationCertificatePassword)
{
if (!string.IsNullOrEmpty(AuthenticationCertificateAsBase64String) &&
AuthenticationCertificatePassword != null)
{
Console.WriteLine("AuthenticationCertificateAsBase64String: " + AuthenticationCertificateAsBase64String);
Console.WriteLine("AuthenticationCertificatePassword: " + AuthenticationCertificatePassword);
return new X509Certificate2(Convert.FromBase64String(AuthenticationCertificateAsBase64String),
AuthenticationCertificatePassword);
}
return null;
}

错误:

{System.Security.Cryptography.CryptographicException: The specified network password is not correct.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password)
at CryptoPlay.Program.AuthenticationCertificate(String AuthenticationCertificateAsBase64String, String AuthenticationCertificatePassword) in d:personalCryptoPlayCryptoPlayProgram.cs:line 154
at CryptoPlay.Program.Main(String[] args) in d:personalCryptoPlayCryptoPlayProgram.cs:line 59
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()}

该错误表明密码不正确,但事实并非如此。如果有人感兴趣,这里是完整的代码供参考(例如,将文件名和密码替换为通用名称)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Pkcs;
namespace CryptoPlay
{
class Program
{
static void Main(string[] args)
{
X509Certificate2 spCert = GetCertificateForUse();
X509Certificate2 encryptCert = GetCertificateUsedForEncryption();
string AuthenticationCertificatePasswordBase64String = EncryptAsBase64String(encryptCert, "Password1!");
Console.WriteLine("AuthenticationCertificatePasswordBase64String:");
Console.WriteLine(AuthenticationCertificatePasswordBase64String);
string AuthenticationCertificatePassword = DecryptFromBase64String(AuthenticationCertificatePasswordBase64String);
Console.WriteLine("AuthenticationCertificatePassword:");
Console.WriteLine(AuthenticationCertificatePassword);
string CertificateAsBase64String = EncryptAsBase64String(encryptCert, spCert);
Console.WriteLine("CertificateAsBase64String");
Console.WriteLine(CertificateAsBase64String);
byte[] rawdata = DecryptBytesFromBase64String(CertificateAsBase64String);
Console.WriteLine("Raw data: " + PrintBytes(rawdata));
string AuthenticationCertificateAsBase64String = Convert.ToBase64String(DecryptBytesFromBase64String(CertificateAsBase64String));
Console.WriteLine("AuthenticationCertificateAsBase64String:");
Console.WriteLine(AuthenticationCertificateAsBase64String);
byte[] rawdata2 = Convert.FromBase64String(AuthenticationCertificateAsBase64String);
Console.WriteLine("Raw data: " + PrintBytes(rawdata2));
if (ByteArrayCompare(rawdata, rawdata2))
Console.WriteLine("Raw data are same");
X509Certificate2 certFromConfig = AuthenticationCertificate(AuthenticationCertificateAsBase64String, AuthenticationCertificatePassword);
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
public static byte[] DecryptBytesFromBase64String(string payloadBase64String, X509Certificate2 decryptingCert = null)
{
try
{
var env = new EnvelopedCms();
env.Decode(Convert.FromBase64String(payloadBase64String));
if (decryptingCert != null)
{
env.Decrypt(new X509Certificate2Collection(decryptingCert));
}
else
{
env.Decrypt();
}
return env.ContentInfo.Content;
}
catch (Exception e)
{
throw new CryptographicException("Failed to decrypt: " + payloadBase64String, e);
}
}
public static string DecryptFromBase64String(string payloadBase64String, X509Certificate2 decryptingCert = null)
{
return Encoding.UTF8.GetString(DecryptBytesFromBase64String(payloadBase64String, decryptingCert));
}
public static string EncryptAsBase64String(X509Certificate2 cert, string payload)
{
return EncryptAsBase64String(cert, Encoding.UTF8.GetBytes(payload));
}
public static string EncryptAsBase64String(X509Certificate2 cert, byte[] payload)
{
var ci = new ContentInfo(payload);
var env = new EnvelopedCms(ci);
env.Encrypt(new CmsRecipient(cert));
return Convert.ToBase64String(env.Encode());
}
public static string EncryptAsBase64String(X509Certificate2 encryptingCert, X509Certificate2 payload)
{
byte[] bytes = payload.Export(X509ContentType.Pfx);
return EncryptAsBase64String(encryptingCert, bytes);
}
private static X509Certificate2 GetCertificateUsedForEncryption()
{
string certPath = "D:\encryptcert.pfx";
string certPassword = "P@ssword123";
var cert = new X509Certificate2(certPath, certPassword, X509KeyStorageFlags.Exportable);
return cert;
}
private static X509Certificate2 GetCertificateForUse()
{
string certPath = "D:\securecert.pfx";
string certPassword = "Password1!";
var cert = new X509Certificate2(certPath, certPassword, X509KeyStorageFlags.Exportable);
return cert;
}
public static X509Certificate2 AuthenticationCertificate(string AuthenticationCertificateAsBase64String, string AuthenticationCertificatePassword)
{
if (!string.IsNullOrEmpty(AuthenticationCertificateAsBase64String) &&
AuthenticationCertificatePassword != null)
{
Console.WriteLine("AuthenticationCertificateAsBase64String: " + AuthenticationCertificateAsBase64String);
Console.WriteLine("AuthenticationCertificatePassword: " + AuthenticationCertificatePassword);
return new X509Certificate2(Convert.FromBase64String(AuthenticationCertificateAsBase64String),
AuthenticationCertificatePassword);
}
return null;
}
public static string PrintBytes(byte[] byteArray)
{
var sb = new StringBuilder("new byte[] { ");
for (var i = 0; i < byteArray.Length; i++)
{
var b = byteArray[i];
sb.Append(b);
if (i < byteArray.Length - 1)
{
sb.Append(", ");
}
}
sb.Append(" }");
return sb.ToString();
}
static bool ByteArrayCompare(byte[] a1, byte[] a2)
{
if (a1.Length != a2.Length)
return false;
for (int i = 0; i < a1.Length; i++)
if (a1[i] != a2[i])
return false;
return true;
}
}
}

您最初的问题是关于将string作为第一个参数的重载,但您的代码使用使用byte[]的重载。

简单的答案是,字符串 one 只是一个文件名,要加载为字节数组,然后调用另一个(它比这更微妙,例如,文件不喜欢符号链接)。

以下类型(由我)已知可以工作:

  • PFX/PKCS#12,DER 编码
  • X.509 证书,DER 编码
  • X.509 证书,PEM+DER 编码 (-----BEGIN CERTIFICATE-----n[etc]n-----END CERTIFICATE-----)
  • PKCS#7 ContentInfo(SignedData),BER 编码(使用由第一个签名者标识的嵌入式证书)
  • PKCS#7 ContentInfo(SignedData),PEM+BER 编码 (-----BEGIN PKCS7-----n...)(使用由第一个签名者标识的嵌入式证书)
  • 验证码签名的文件(.exe、.dll、.msi、.msp 等)(它使用第一个签名者的证书)

是否传入密码与 Blob 被标识为哪种文件格式无关。 除非配置文件或临时目录位于 SMB/CIFS 共享上,否则 Windows 报告ERROR_BAD_PASSWORD意味着它认为你的字节表示 PFX,但无法使用输入密码作为密钥验证 PFX MAC。 我建议检查密码变量中嵌入的换行符或换行符(或空值);或前导空格或尾随空格。

最新更新