Я создал самозаверяющий сертификат с помощью команды приглашения
csptest -keyset -newkeyset -makecert -container test3 -keytype exchange
Затем я установил его с помощью стороннего приложения. Когда я пытаюсь получить сертификат PrivateKey
в основном приложении asp.net, он выдает NotSupportedException
.
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
certificates = store1.Certificates;
var certificate = GetCertificateByThumbprint(certificates, "51F9748FE7DDE895DD100AAD0BE54C1ACF6B4DCC");
if (certificate.HasPrivateKey)
{
var kayAlgorithm = = _certificate.GetKeyAlgorithm(); // same as certificate.PublicKey.Oid.Value;
var rsaPrivateKey = certificate.GetRSAPrivateKey();
var dsaPrivateKey = _certificate.GetDSAPrivateKey();
var ecdsaPrivateKey = _certificate.GetECDsaPrivateKey();
var privateKey = certificate.PrivateKey;
}
HasPrivateKey
, возвращает true. GetRSAPrivateKey
, GetDSAPrivateKey
и GetECDsaPrivateKey
возвращают ноль. Однако GetKeyAlgorithm
(oid.value) возвращает «1.2.643.7.1.1.1.1». Я углубился в библиотеку System.Security.Cryptography.X509Certificates.X509Certificate2
и обнаружил там жестко закодированную проверку только для алгоритмов "1.2.840.113549.1.1.1" или "1.2.840.10040.4.1".
public AsymmetricAlgorithm PrivateKey
{
get
{
this.ThrowIfInvalid();
if (!this.HasPrivateKey)
return (AsymmetricAlgorithm) null;
if (this._lazyPrivateKey == null)
{
string keyAlgorithm = this.GetKeyAlgorithm();
if (!(keyAlgorithm == "1.2.840.113549.1.1.1"))
{
if (!(keyAlgorithm == "1.2.840.10040.4.1"))
throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
this._lazyPrivateKey = (AsymmetricAlgorithm) this.Pal.GetDSAPrivateKey();
}
else
this._lazyPrivateKey = (AsymmetricAlgorithm) this.Pal.GetRSAPrivateKey();
}
return this._lazyPrivateKey;
}
set
{
throw new PlatformNotSupportedException();
}
}
В .net framework получается PrivateKey
выдает то же исключение. System.Security.Cryptography.X509Certificates.X509Certificate2
выглядит иначе.
public AsymmetricAlgorithm PrivateKey
{
get
{
if (!this.HasPrivateKey)
return (AsymmetricAlgorithm) null;
if (this.m_privateKey == null)
{
CspParameters parameters = new CspParameters();
if (!X509Certificate2.GetPrivateKeyInfo(this.m_safeCertContext, ref parameters))
return (AsymmetricAlgorithm) null;
parameters.Flags |= CspProviderFlags.UseExistingKey;
switch (this.PublicKey.AlgorithmId)
{
case 8704:
this.m_privateKey = (AsymmetricAlgorithm) new DSACryptoServiceProvider(parameters);
break;
case 9216:
case 41984:
this.m_privateKey = (AsymmetricAlgorithm) new RSACryptoServiceProvider(parameters);
break;
default:
throw new NotSupportedException(SR.GetString("NotSupported_KeyAlgorithm"));
}
}
return this.m_privateKey;
}
set
{
...
}
}
Итак, как я могу получить PrivateKey
для другого алгоритма или я что-то не так сделал раньше?
GetCertificateByThumbprint
исходный код метода только вкейс. (Я не смог использовать метод X509Certificate2Collection.Find
, поскольку он не возвращает мой сертификат, поскольку он недействителен)
private X509Certificate2 GetCertificateByThumbprint(X509Certificate2Collection certifcates, string thumbprint)
{
foreach (var certificate in certifcates)
{
if (certificate.Thumbprint == thumbprint)
return certificate;
}
}