Как Createx509certificate2 предоставляет байты сертификата и закрытый ключ - dnx50

В основном я использую службу LetsEncrypt, чтобы вернуть байт сертификата [], который я могу превратить в X509Certificate2, но тогда ему не хватает закрытого ключа, чтобы затем использовать его в SSLStream. У меня есть закрытый ключ в виде RSAParameters, но я также могу преобразовать его в байт [], но я не могу найти способ собрать 2 вместе в одном и том же X509Certificate2, чтобы я мог использовать его для AuthenticateAsServer в SSLStream. Насколько я могу судить, методы, которые вы использовали бы для dotnet 4, не подходят для dnx50. Мой рабочий пример был бы идеальным, и я хочу сохранить решение в dnx50, так как я хочу развернуть его в коробках Linux и Windows.

В основном пытаясь сделать что-то похожее на Convert Certificate and Закрытый ключ в .PFX программно на C#, но моей следующей задачей будет просто создать X509 с закрытым ключом, хотя сохранение будет.

Из того, что я могу сказать на данный момент, я думаю, что dnx50 не позволяет вам создать объект сертификата, а затем добавить к нему закрытый ключ, как это сделал dotnet 4. Вместо этого я думаю, что мне нужно передать файл или байт [], который содержит оба, чтобы это работало, но я не знаю, как объединить мои 2-байтовые массивы вместе или отформатировать их.


person Seer    schedule 29.03.2016    source источник


Ответы (1)


Наконец выработал решение для этого. Не идеально, но работает. По сути, он использует bouncyCastle для создания потока pfx, а затем вы можете прочитать его, чтобы загрузить закрытый ключ с сертификатом. Для этого в CoreCLR я использовал пакет nuget Portable.BouncyCastle:1.8.1 со следующим кодом, который я поместил во вспомогательный класс.

public X509Certificate2 CreateX509Certificate2(RSAParameters keys, byte[] certificateBytes, string friendlyName)
    {

        if (string.IsNullOrWhiteSpace(friendlyName))
        {
            friendlyName = "default";
        }

        var store = new Pkcs12Store();
        var convertedKeys = GetRsaKeyPair(keys);
        var certificate = new X509CertificateParser().ReadCertificate(certificateBytes);

        store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(convertedKeys.Private), new X509CertificateEntry[] { new X509CertificateEntry(certificate)});
        using (MemoryStream ms = new MemoryStream())
        {
            var random = new SecureRandom();
            string password = random.Next().ToString() + random.Next().ToString() + random.Next().ToString();
            store.Save(ms, password.ToCharArray(), random);
            var cert = new X509Certificate2(ms.ToArray(), password, X509KeyStorageFlags.Exportable);
            return cert;
        }
    }


    private AsymmetricCipherKeyPair GetRsaKeyPair(
       RSAParameters rp)
    {
        BigInteger modulus = new BigInteger(1, rp.Modulus);
        BigInteger pubExp = new BigInteger(1, rp.Exponent);

        RsaKeyParameters pubKey = new RsaKeyParameters(
            false,
            modulus,
            pubExp);

        RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
            modulus,
            pubExp,
            new BigInteger(1, rp.D),
            new BigInteger(1, rp.P),
            new BigInteger(1, rp.Q),
            new BigInteger(1, rp.DP),
            new BigInteger(1, rp.DQ),
            new BigInteger(1, rp.InverseQ));

        return new AsymmetricCipherKeyPair(pubKey, privKey);
    }
person Seer    schedule 30.03.2016