<PackageReference Include="BouncyCastle.Cryptography" Version="2.3.0" />

BcDefaultTlsCredentialedDecryptor

Credentialed class decrypting RSA encrypted secrets sent from a peer for our end of the TLS connection using the BC light-weight API.
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Encodings; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Tls.Crypto.Impl.BC { public class BcDefaultTlsCredentialedDecryptor : TlsCredentialedDecryptor, TlsCredentials { protected readonly BcTlsCrypto m_crypto; protected readonly Certificate m_certificate; protected readonly AsymmetricKeyParameter m_privateKey; public virtual Certificate Certificate => m_certificate; public BcDefaultTlsCredentialedDecryptor(BcTlsCrypto crypto, Certificate certificate, AsymmetricKeyParameter privateKey) { if (crypto == null) throw new ArgumentNullException("crypto"); if (certificate == null) throw new ArgumentNullException("certificate"); if (certificate.IsEmpty) throw new ArgumentException("cannot be empty", "certificate"); if (privateKey == null) throw new ArgumentNullException("privateKey"); if (!privateKey.IsPrivate) throw new ArgumentException("must be private", "privateKey"); if (!(privateKey is RsaKeyParameters)) throw new ArgumentException("'privateKey' type not supported: " + privateKey.GetType().FullName); m_crypto = crypto; m_certificate = certificate; m_privateKey = privateKey; } public virtual TlsSecret Decrypt(TlsCryptoParameters cryptoParams, byte[] ciphertext) { return SafeDecryptPreMasterSecret(cryptoParams, (RsaKeyParameters)m_privateKey, ciphertext); } protected virtual TlsSecret SafeDecryptPreMasterSecret(TlsCryptoParameters cryptoParams, RsaKeyParameters rsaServerPrivateKey, byte[] encryptedPreMasterSecret) { SecureRandom secureRandom = m_crypto.SecureRandom; ProtocolVersion rsaPreMasterSecretVersion = cryptoParams.RsaPreMasterSecretVersion; bool flag = false; byte[] array = new byte[48]; secureRandom.NextBytes(array); byte[] array2 = Arrays.Clone(array); try { Pkcs1Encoding pkcs1Encoding = new Pkcs1Encoding(new RsaBlindedEngine(), array); pkcs1Encoding.Init(false, new ParametersWithRandom(rsaServerPrivateKey, secureRandom)); array2 = pkcs1Encoding.ProcessBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.Length); } catch (Exception) { } if (!flag || TlsImplUtilities.IsTlsV11(rsaPreMasterSecretVersion)) { int num = (rsaPreMasterSecretVersion.MajorVersion ^ (array2[0] & 255)) | (rsaPreMasterSecretVersion.MinorVersion ^ (array2[1] & 255)); num = num - 1 >> 31; for (int i = 0; i < 48; i++) { array2[i] = (byte)((array2[i] & num) | (array[i] & ~num)); } } return m_crypto.CreateSecret(array2); } } }