none
https proxy server : how to ignore the warning of not priviate connection RRS feed

  • Question

  • i'm tryng to create an http proxy server that can read https requests

    i  open up an SSL stream and Authenticated as client to remote server

     then i created a certificate with makecert,  open up  an ssl stream Authenticate as server for the browser.

    and read and write the data from the ssl streams

    but when i'm trying to enter the gmail, for example, i get the warning that my connection is not priviate.

    i try to wrote lines like:

    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    
    
    או
    
                ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;
    
    או
               ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, errors) => true;
    
                ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; };
    
                // 255 characters - lots of code!
                ServicePointManager.ServerCertificateValidationCallback =
                    new RemoteCertificateValidationCallback(
                        delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
                        {
                            return true;
                        })

    but any thing didn't work.

    what can i do?

    Wednesday, March 14, 2018 10:23 AM

All replies

  • Hi teacherh,

    >> when i'm trying to enter the gmail, for example, i get the warning that my connection is not priviate.

    What do you mean by this? Could you share us the complete steps you received this error?

    “ServicePointManager.ServerCertificateValidationCallback” is used to configure how the client valid the server certificate.

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, March 15, 2018 4:45 AM
  • hi,

    my complete steps are:

    1. create a certificate with makecert

    for ssl requests:

    4 - parse the request for the server address

    5 - create a new socket and bind to this address

    6 - get the server side SSL stream and authenticate


    SslStream

     

    sslStreamServerSide = new SslStream(destinationStream, falsenew RemoteCertificateValidationCallback(ValidateServerCertificate), null);

     

    string strSSLResponse = "";
    byte[] bytSSLResponse;
    try
    {
    sslStreamServerSide.AuthenticateAsClient(strDestAddr);
    }
    catch (AuthenticationException ex)
    {
    //bad certificate 
    strSSLResponse = "HTTP/1.0 401 Bad Certificate\r\n\r\n";
    bytSSLResponse = Encoding.UTF8.GetBytes(strSSLResponse);
    browserStream.Write(bytSSLResponse, 0, bytSSLResponse.Length);
    browserStream.Flush();

     

    return false;
    }

    7 - send an 'ok' response back to the browser. DONT CLOSE THE SOCKET YET.

    strSSLResponse =

    "HTTP/1.0 200 Connection established\r\n\r\n";
    bytSSLResponse = Encoding.UTF8.GetBytes(strSSLResponse);
    browserStream.Write(bytSSLResponse, 0, bytSSLResponse.Length);
    browserStream.Flush();


    8 - the browser will have sent an SSL 'hello' message, so authenticate as a server now

    (i wrote my own function to return a dummy certificate, i also tried to create self certificate with make cert, but on the two options i got the warning that my connection is not priviate)

    serverCert = GetDummyCertificate("MyTestServer");
    SslStream sslStreamClientSide = new SslStream(browserStream, false);
    sslStreamClientSide.AuthenticateAsServer(serverCert);

     9 - use the browser side SSL stream to receive the actual encrypted data 

    10- send the decrypted data to the server using the server side SSL stream. with the SSLStream.Write method .
    11 - wait for a response from the server using the SSLStream.Read method and send the response back to the browser. 
    12 - just basically repeat the above until the browser and server have finished.

    13 - CLOSE THE SERVER SOCKET AND THE BROWSER SOCKET

    14 - when i run my proxy and tried to access to a secure site i got the warning from the browser that my connection is not priviate.

    thanks

    Saturday, March 17, 2018 9:15 PM
  • Hi teacherh,  

    Thank you for posting in the MSDN Forum.

    I'm trying to involve some senior engineers into this issue and it will take some time. Your patience will be greatly appreciated.

    Sorry for any inconvenience and have a nice day!

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, March 20, 2018 2:07 AM
  • Dear forum user,

    Below link lists some ways to fix the issue about "your connection is not a private connection".

    https://usefulpcguide.com/16666/your-connection-is-not-private/

    I hope is helpful for you.

    Your question falls into a category which requires a more in-depth level of support. Please visit the below link to see the various free and paid support options that are available to better meet your needs. http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone


    Best Regards,

    Victor Yao


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Thursday, March 22, 2018 3:27 AM
  • i understand that to solve my problem I have to create a certificate for every single request.

    what I need to do is:

    • step 1:  create a self-signed root certificate as a certificate authority
      •  install this in the clients "Trusted Root Certification Authorities" store.
    • step 2:  create the server certificates on-the-fly for every incoming request
      • sign this certificates with the root certificates tree to set the issuer
      • I can cache the certificates in files or in a system certificate store if needed.

    (this is completely the same in fiddler)

    so my code to step 1 is:

     
    caPrivateKey = null;
               X509Certificate2 caCert = GenerateCACertificate("CN=MyROOTCA", ref caPrivateKey);
            addCertToStore(caCert, StoreName.Root, StoreLocation.LocalMachine);
    
    
    public static X509Certificate2 GenerateCACertificate(string subjectName, ref AsymmetricKeyParameter CaPrivateKey)
        {
            const int keyStrength = 2048;
    
            // Generating Random Numbers
            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
            SecureRandom random = new SecureRandom(randomGenerator);
    
            // The Certificate Generator
            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
    
            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
            certificateGenerator.SetSerialNumber(serialNumber);
    
            // Signature Algorithm
            const string signatureAlgorithm = "SHA256WithRSA";
            certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);
    
            // Issuer and Subject Name
            X509Name subjectDN = new X509Name(subjectName);
            X509Name issuerDN = subjectDN;
            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);
    
            // Valid For
            DateTime notBefore = DateTime.UtcNow.Date;
            DateTime notAfter = notBefore.AddYears(2);
    
            certificateGenerator.SetNotBefore(notBefore);
            certificateGenerator.SetNotAfter(notAfter);
    
            // Subject Public Key
            AsymmetricCipherKeyPair subjectKeyPair;
            KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            subjectKeyPair = keyPairGenerator.GenerateKeyPair();
    
            certificateGenerator.SetPublicKey(subjectKeyPair.Public);
    
            // Generating the Certificate
            AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
    
            // selfsign certificate
            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerKeyPair.Private, random);
            X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
    
            CaPrivateKey = issuerKeyPair.Private;
    
            return x509;
            //return issuerKeyPair.Private;
    
        }
    
        public static bool addCertToStore(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, System.Security.Cryptography.X509Certificates.StoreName st, System.Security.Cryptography.X509Certificates.StoreLocation sl)
        {
            bool bRet = false;
    
            try
            {
                X509Store store = new X509Store(st, sl);
                store.Open(OpenFlags.ReadWrite);
                store.Add(cert);
    
                store.Close();
            }
            catch
            {
    
            }
    
            return bRet;
        }

    and for step 2- for any request:

      
    X509Certificate2 SiteCert = GenerateSelfSignedCertificate("CN=" + uri.Host, "CN=MyROOTCA", caPrivateKey);
                    addCertToStore(SiteCert, StoreName.CertificateAuthority, StoreLocation.LocalMachine);
    sslStreamClientSide = new SslStream(clientStream, false);
                    try
                    {
                        sslStreamClientSide.AuthenticateAsServer(SiteCert, false, SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, true);
                    
                    }
                    catch (Exception)
                    {
                        sslStreamClientSide.Close();
                      
                        clientStream.Close();
                       
                        return;
                    }
    the generate self sign certificate function:
    public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey)
        {
            const int keyStrength = 2048;
    
            // Generating Random Numbers
            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
            SecureRandom random = new SecureRandom(randomGenerator);
    
            // The Certificate Generator
            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
    
            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
            certificateGenerator.SetSerialNumber(serialNumber);
    
            // Signature Algorithm
            const string signatureAlgorithm = "SHA256WithRSA";
            certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);
    
            // Issuer and Subject Name
            X509Name subjectDN = new X509Name(subjectName);
            X509Name issuerDN = new X509Name(issuerName);
            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);
    
            // Valid For
            DateTime notBefore = DateTime.UtcNow.Date;
            DateTime notAfter = notBefore.AddYears(2);
    
            certificateGenerator.SetNotBefore(notBefore);
            certificateGenerator.SetNotAfter(notAfter);
    
            // Subject Public Key
            AsymmetricCipherKeyPair subjectKeyPair;
            var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            var keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            subjectKeyPair = keyPairGenerator.GenerateKeyPair();
    
            certificateGenerator.SetPublicKey(subjectKeyPair.Public);
    
            // Generating the Certificate
            AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
    
            // selfsign certificate
            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerPrivKey, random);
    
    
            // correcponding private key
            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
    
    
            // merge into X509Certificate2
            X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());
    
            Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded());
            if (seq.Count != 9)
            {
                //throw new PemException("malformed sequence in RSA private key");
            }
    
            RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq);
            RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);
    
            x509.PrivateKey = ToDotNetKey(rsaparams); //x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
            return x509;
    
        }
    
        public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey)
        {
            var cspParams = new CspParameters
            {
                KeyContainerName = Guid.NewGuid().ToString(),
                KeyNumber = (int)KeyNumber.Exchange,
                Flags = CspProviderFlags.UseMachineKeyStore
            };
    
            var rsaProvider = new RSACryptoServiceProvider(cspParams);
            var parameters = new RSAParameters
            {
                Modulus = privateKey.Modulus.ToByteArrayUnsigned(),
                P = privateKey.P.ToByteArrayUnsigned(),
                Q = privateKey.Q.ToByteArrayUnsigned(),
                DP = privateKey.DP.ToByteArrayUnsigned(),
                DQ = privateKey.DQ.ToByteArrayUnsigned(),
                InverseQ = privateKey.QInv.ToByteArrayUnsigned(),
                D = privateKey.Exponent.ToByteArrayUnsigned(),
                Exponent = privateKey.PublicExponent.ToByteArrayUnsigned()
            };
    
            rsaProvider.ImportParameters(parameters);
            return rsaProvider;
        }

    but still it give me the alert that my connection is not priviate...

    can you help me what i missed?

    thanks a lot!

    Thursday, April 12, 2018 12:13 AM