Как импортировать ключи PKCS1 из файла PEM, содержащего закрытые / открытые ключи в .Net Core - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь загрузить закрытый и открытый ключи из файла PEM, используя .Net Core.Мой код выглядит так:

var localPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var path = Path.Combine(localPath, this._configManager.JwtPem);
var rsaCryptoServiceProvider = new RSACryptoServiceProvider();

var linesList = File.ReadAllLines(path).ToList();
var line = string.Concat(linesList.GetRange(1, linesList.Count - 2));

rsaCryptoServiceProvider.ImportCspBlob(Convert.FromBase64String(line));

Исключение, которое я получаю:

Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException : Bad Version of provider
   at Internal.NativeCrypto.CapiHelper.ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFlags flags, Boolean addNoSaltFlag, Byte[] keyBlob, SafeKeyHandle& safeKeyHandle)
   at System.Security.Cryptography.RSACryptoServiceProvider.ImportCspBlob(Byte[] keyBlob)
   at StepNexusCA.ServiceLayer.Authorization.TokenService.GenerateToken(List`1 claims)

Файл PEM, содержащий формат PKCS1 моей разработки. Закрытые / открытые ключи находятся здесь:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAwgs8kmIwk+4geRO7dGZjzYpgD2OiaUrnOOIk+ObXt/CcjhwX
lSst+jBmfMF1Wp/mF4aUQsePxN59MYV2BsqPLEkzVdq/fb/7V2wbZcooJAQKkJwT
emtYHrBN00KBBeu9uQZlFOw365ij4GrbP7mcr4tNFZ3TPnRFUUFqhvB6mEG1aZsb
lOn1lgL34tAycQHNxttXz/aGfPyTefQ+yISvSY2n8288OVlyfu6wKDONQYS+/stC
tCV+a+/dDUSUjaZsXM1+BMSflsINqIcCTCMvPa6fb5Z+USfPDcDNwzUyX20LBzH5
wFwPLIvuoqJeeczcaHaT+dS2ZZREj6kgUsdC+QIBAwKCAQEAgVzTDEF1t/QVpg0n
ou7tM7GVX5fBm4dE0JbDUJnlJUsTCWgPuMdz/CBEUyujkb/uulm4LIUKgz7+IQOk
BIcKHYYiOTx/qSqnj51nmTFwGAKxtb1iUZzlacrejNcArp0pJgRDY0glR7sX6vHn
f9ETH7IzY76M1E2Di4Dxr0r8ZX/3ozsrSXp+GMJLeN9sCjKSyxoE5Y71eDBTCX2N
tShJJjhqUDz61bhKlX9j5c3jWvTXx46dE8wjoJ/BW1XJo5J1gzHQ/OLYeOXIdxlj
jVSlEuU69UT588B7UEEK9N9xK5K/c0Yw5gd02RUv/o7qdpYQICeGtQMMaFkm75xy
nUOxwwKBgQD/orUvgNJfFKyvGY8XJTuek5q8IcFD8AFO3b7pNnPynw8llyEpACAv
Onf9aJSPZvtrabSqrpO8k8Ijyhe2Ino39GuRV8RURl46GmFN31RoYV1wHI4K7Emh
68cdKbCEBudog+kImImldBAfo+QmBtqhS+u4B5qQwwnFa8DriQoiYwKBgQDCUg0r
Jd/ZXDLXk/H5PHpTApmUVd7SWLLIDfkBAlRO8Sni4/Ka+KTTZDec5uoo0hoP6cCs
Z9+MZz4XOiwv9dCEI5czMawGmwsm23+fGM/PP/lW4yD8dz10KZggKjWElymDVl+n
zsc6ctwHAOfYwREi7E+R4rWTBgTEvH2I3deV8wKBgQCqbHjKVeGUuHMfZl9kw30U
YmcoFoDX9VY0k9SbeaKhv19uZMDGABV00aVTmw2071JHm83HHw0oYoFtMWUkFvwl
TZ0Lj9g4Lul8EZYz6jhFlj5KvbQHSDEWnS9oxnWtWe+bAptbEFvDorVqbULEBJHA
3UfQBRG111vY8oCdBgbBlwKBgQCBjAjHbpU7ksyPt/amKFGMrGZi4+nhkHcwCVCr
VuLfS3FB7UxnUG3iQs+970bF4Wa1RoBy7+pdmilk0XLKo+BYF7oiIR1ZvLIZ56pq
EIqKKqY57MCoT35NcRAVcXkDD3ECOZUaidom9z1aAJqQgLYXSDUL7HkMrq3YfakF
6Tpj9wKBgEPCSW7EMFjK2NzmB+4b+skxXcfCZ0ldNtwoUDijuAMFg8ueC3j2qFUX
bAXSApi3mQMow1/JwQxiZ+b+GDLdTcE/PrBVBRkL/5RkmnVagbjBrdZhVjpC+dUo
eEkCChClGGpRyPJ+DYYRyX1Fk9Und8Xbd49Vv+/6RL76ys3gGQl8
-----END RSA PRIVATE KEY-----

Почему я не могу импортировать ключ с помощью ImportCspBlob (...)?Я не нашел много информации в Интернете относительно исключения, но где мой код неверен?Мне известно о BouncyCastle, но я пытаюсь сделать это с помощью .Net Core.

Ответы [ 4 ]

0 голосов
/ 10 июля 2019

Существует множество онлайн-инструментов для конвертации PEM в XML, просто конвертируйте ваш pem в xml, а затем

RSA.FromXmlString(string xmlString)

0 голосов
/ 23 ноября 2018

Если вам не нужно преобразовывать PEM в DER в коде, вы можете использовать openssl для получения файла закрытого ключа в кодировке DER:

openssl rsa -in key.pem -out key.der -outform der

0 голосов
/ 29 ноября 2018

.Net Cryptographic API не поддерживает широко используемые в отрасли файлы PEM, поэтому нам необходимо преобразовать его в формат XML, представленный Microsoft.В основном, решение было найдено в другом подобном вопросе C # Извлечение открытого ключа из закрытого ключа RSA PEM .

0 голосов
/ 23 ноября 2018

Форматом ImportCspBlob является формат из ExportCspBlob, который является форматом BLIV-объекта PRIVATEKEY, требуемого для CryptImportKey .Поскольку .NET просто прозрачно передает это в CAPI Windows, метод ImportCspBlob генерирует на платформах, отличных от Windows.

Другой ответ, который я давал в прошлом для импорта закрытых ключей (включая PKCS # 1 RSAPrivateKey), -немного мета-ответа, который включает в себя ссылки, чтобы просто заставить все работать: Цифровая подпись в c # без использования BouncyCastle .

Ежедневные сборки .NET Core 3.0 имеют встроенную функциональностьв.В основном.Формат PEM прост на практике, но несколько раздражает в спецификации, поэтому методы оставляют вызывающей стороне "un-PEM" данные ... для форматирования по умолчанию для полезной нагрузки с одним значением без атрибутов (например,в вашем примере) вы можете сделать это с ежедневными сборками через

private static RSA ReadKeyFromFile(string filename)
{
    string pemContents = System.IO.File.ReadAllText(filename);
    const string RsaPrivateKeyHeader = "-----BEGIN RSA PRIVATE KEY-----";
    const string RsaPrivateKeyFooter = "-----END RSA PRIVATE KEY-----";

    if (pemContents.StartsWith(RsaPrivateKeyHeader))
    {
        int endIdx = pemContents.IndexOf(
            RsaPrivateKeyFooter,
            RsaPrivateKeyHeader.Length,
            StringComparison.Ordinal);

        string base64 = pemContents.Substring(
            RsaPrivateKeyHeader.Length,
            endIdx - RsaPrivateKeyHeader.Length);

        byte[] der = Convert.FromBase64String(base64);
        RSA rsa = RSA.Create();
        rsa.ImportRSAPrivateKey(der, out _);
        return rsa;
    }

    // "BEGIN PRIVATE KEY" (ImportPkcs8PrivateKey),
    // "BEGIN ENCRYPTED PRIVATE KEY" (ImportEncryptedPkcs8PrivateKey),
    // "BEGIN PUBLIC KEY" (ImportSubjectPublicKeyInfo),
    // "BEGIN RSA PUBLIC KEY" (ImportRSAPublicKey)
    // could any/all be handled here.
    throw new InvalidOperationException();
}

Ежедневные сборки .NET Core SDK можно получить по https://github.com/dotnet/core-sdk/#installers-and-binaries

...