#c# #.net #cryptography #certificate #bouncycastle
#c# #.net #криптография #сертификат #BouncyCastle
Вопрос:
Использование .NET Core 3.1 и BouncyCastle
У меня есть закрытый ключ ECC от Pkcs12. Как я могу сохранить это в X509Certificate2 закрытый ключ, пожалуйста? Причина, по которой я пытаюсь сделать это таким образом, заключается в том, что когда я загружаю Pkcs12 как X509Certificate2, X509Certificate2.PrivateKey
метод выдает исключение «не реализовано / алгоритм не поддерживается».
Это то, что у меня есть до сих пор:
using var stream = new MemoryStream(myPkcs12);
Pkcs12Store pstore = new Pkcs12Store(stream, password.ToCharArray());
var name = "";
foreach (string alias in store.Aliases)
{
if (pstore.IsKeyEntry(alias))
{
name = alias;
}
}
var key = pstore.GetKey(name);
var cert = new X509Certificate2(myPkcs12, "mypassword", X509KeyStorageFlags.EphemeralKeySet | X509KeyStorageFlags.Exportable);
cert.PrivateKey = // key? I imagine it is incorrect to use DotNetUtilities.ToRSA()?
Спасибо!
Обновить:
Причина этого сообщения связана с этой проблемой:
private const string EccTestCert = "MIINbQIBAzCCDSkGCSqGSIb3DQEHAaCCDRoEgg0WMIIN.... 9wQUpQgYbgB7yknIW7Oaz3hogAVihJoCAgfQ";
var cert = new X509Certificate2(Convert.FromBase64String(EccTestCert), "1");
// If you inspect it, the PrivateKey throws an exception. Whilst with an RSA cert, it will not.
Комментарии:
1. PKCS #12 содержит сертификат и закрытый ключ. Таким образом, при импорте pkcs12 с
new X509Certificate2(myPkcs12...)
экземпляром предоставляется сертификат с закрытым ключом, чтобы вы могли его подписать или расшифровать.2. @DanielFisherlennybacon Привет, когда я пытаюсь сделать это с помощью сертификата ECC, X509Certificate не может вернуть мне PrivateKey для использования. Я буду обновлять с помощью примера Pkcs12.
Ответ №1:
Источник показывает, что в зависимости от платформы, на которой вы работаете, генерируется исключение.
switch (GetKeyAlgorithm())
{
case Oids.Rsa:
_lazyPrivateKey = Pal.GetRSAPrivateKey();
break;
case Oids.Dsa:
_lazyPrivateKey = Pal.GetDSAPrivateKey();
break;
default:
// This includes ECDSA, because an Oids.EcPublicKey key can be
// many different algorithm kinds, not necessarily with mutual exclusion.
//
// Plus, .NET Framework only supports RSA and DSA in this property.
throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
}
Закрытый ключ типа AsymmetricAlgorithm
witch в любом случае должен быть передан в RSA или ECDsa. Я помню, как @bartonjs говорил, что нужно использовать GetXXXPrivateKey()
методы. Так что вы можете сделать это самостоятельно:
string EccTestCert = "{base64-pkcs-12-here}";
var cert = new X509Certificate2(Convert.FromBase64String(EccTestCert), "1");
if (cert.HasPrivateKey) {
var key =
(AsymmetricAlgorithm) cert.GetRSAPrivateKey()
?? cert.GetECDsaPrivateKey()
?? throw new NotSupportedException("Who still uses DSA?");
if (key is ECDsa ecdsa) {
var ecdsaSignature = ecdsa.SignData(new byte[]{ 0x00}, HashAlgorithmName.SHA256);
} else if (key is RSA rsa) {
var rsaSignature = rsa.SignData(new byte[]{ 0x00}, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
} else {
throw new NotSupportedException("Who still uses DSA?");
}
}
Комментарии:
1. @PKCS12 если это вы проголосовали, и это отвечает на ваш вопрос, не могли бы вы принять его как подходящий?
2. Спасибо. Не возражаете ли вы удалить или скремблировать Pkcs12 любезно?
3. Добро пожаловать. Данные заменены на место держателя.
4. » Я помню, @bartonjs говорил, что нужно использовать методы GetXXXPrivateKey()». Ура, я наконец-то достучался до людей!
5. До сих пор наши пути пересекались не один раз 🙂