Trying to support TLS1.2, but get error: Could not create SSL/TLS secure channel

ejecarpet
New Community Member

I understand there is a deadline to support TLS1.2 when making calls to PayPal Express from my ASP.Net app, however, I keep getting the following error:

"Could not create SSL/TLS secure channel" whenever I attempt to make a call to the sandbox (now that the sandbox no longer supports anything less than version 1.2 of TLS).
The site is version 4.6.1 of DotNet (which fully supports TLS1.2) and my test client supports TLS1.2 as well as all the browsers and software on the machine (both Win 2012 Server and Win 8.1 Desktop), so I am 100% positive that the problem lies in the paypal_base.dll file.
I notice that the paypal_base.dll file is no longer anywhere to be found.  
The version I have is old (Version 4.1.0.0), but I found a newer version (Version 5.6.92) and still have the identical problem - neither supports TLS 1.2.
Is there any way that there is another version of paypal_base.dll that supports TLS1.2 ?  I've scoured the Internet looking for this file, to no avail.

I've spent days trying to get this to work, but no joy - it SHOULD work, but I believe the dll is the problem.

Is this deprecated? If so, why is there no mention of this anywhere?
Do I just need to completely re-write the payment system to the new format?  At wit's end (and running out of time!) HELP!


Login to Me Too
5 REPLIES 5

abs321
Contributor
Contributor

Yes, I'm having the same problem and believe the issue could be in the dll.

 

The following request/response between the 'paypal_base.dll' and paypal was captured using fiddler.

 

Version: 3.1 (TLS/1.0)
Random: 5B 20 88 68 36 CC A4 48 F8 AD 69 34 1A 69 49 F7 85 28 78 42 F9 7D 7E 1F 1E EB 29 DC 8B ED C3 B8
"Time": 7/28/2025 6:14:03 PM
SessionID: empty
Extensions:
server_name api-aa.sandbox.paypal.com
elliptic_curves secp256r1 [0x17], secp384r1 [0x18]
ec_point_formats uncompressed [0x0]
extended_master_secret empty
renegotiation_info 00

This was the response returned by paypal.

 

HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 19:54:35.556
Connection: close

fiddler.network.https> HTTPS handshake to api-aa.sandbox.paypal.com (for #383) failed. System.Security.Authentication.AuthenticationException A call to SSPI failed, see inner exception. < The message received was unexpected or badly formatted

Win32 (SChannel) Native Error Code: 0x80090326

I did a .net upgrade and got the same results, but I did some googeling and found out that .net 4.5 requires you to opt-in, to use TLS 1.2 by default, so i placed the following line in my global.asax.

 

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

That change definitely changed the connection request. As you can see, it has changed from TLS/1 to TLS/1.2, however, I received the same response.

 

Version: 3.3 (TLS/1.2)
Random: 5B 20 87 6B F1 95 73 BF A3 27 FA 72 4F 93 5E 20 4D 67 33 EC A4 61 A9 45 E8 C3 49 DD CE 86 0E 15
"Time": 3/2/2027 12:02:35 PM
SessionID: empty
Extensions:
server_name api-aa.sandbox.paypal.com
elliptic_curves secp256r1 [0x17], secp384r1 [0x18]
ec_point_formats uncompressed [0x0]
signature_algs sha512_rsa, sha512_ecdsa, sha256_rsa, sha384_rsa, sha1_rsa, sha256_ecdsa, sha384_ecdsa, sha1_ecdsa, sha1_dsa
extended_master_secret empty
renegotiation_info 00

This was the response returned by paypal. Smiley Sad

HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 19:54:35.556
Connection: close

fiddler.network.https> HTTPS handshake to api-aa.sandbox.paypal.com (for #383) failed. System.Security.Authentication.AuthenticationException A call to SSPI failed, see inner exception. < The message received was unexpected or badly formatted

Win32 (SChannel) Native Error Code: 0x80090326

I've double checked the API Username, API Password, and Signature but i'm not sure if they are used when creating the HTTPS connection.

 

Anyhow, would really appreciate some help with this.

 

 

Login to Me Too

eje2000
Contributor
Contributor

I ran into this problem as well (never could get it to work - perhaps there's a return port that is not accepted? not sure, gave up on it a couple of weeks ago), so I completely rewrote it to support the latest REST API and got it working perfectly in the sandbox, now trying to get it to work live (with no joy - 401 unauthorized error w/ no solutions in site - many posts, no responses, still no response from Paypal tech support - and time is running out fast!).

Login to Me Too

abs321
Contributor
Contributor

OK,

 

I got it working. 

 

I got the .NET Tls12 opt-in form the following resource.

https://stackoverflow.com/a/39766105

 

I got some configuration information from the following resource.

https://stackoverflow.com/a/13372262

 

I opened up the "paypal_base, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b37401294aaf5617" dll in "ILSpy" and reviewed the configuration parser and found the following function.

 

public static Hashtable ReadEndpoints(XmlNode root)
{
	if (root == null)
	{
		throw new ArgumentNullException("node");
	}
	Hashtable hashtable = new Hashtable();
	XmlNode xmlNode = root.SelectSingleNode("wsdl/@min-version");
	XmlNode xmlNode2 = root.SelectSingleNode("wsdl/@max-version");
	LogIfNull(xmlNode, "min-version attribute not found in endpoints");
	LogIfNull(xmlNode2, "max-version attribute not found in endpoints");
	XmlNodeList xmlNodeList = root.SelectNodes("wsdl/environment");
	if (NonNull(xmlNode, xmlNode2, xmlNodeList))
	{
		...
	}
	return hashtable;
}

 

The parsing code looks to be branching on the versions so i added them to the configuration.

 

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
    <section name="paypal" type="com.paypal.sdk.core.ConfigSectionHandler, paypal_base"/>
  </configSections>

  <paypal>
    <endpoints>
      <wsdl min-version="0" max-version="100">
        <environment name="live">
          <port name="PayPalAPI">https://api.paypal.com/2.0/</port>
          <port name="PayPalAPIAA">https://api-aa.paypal.com/2.0/</port>
          <port name="PayPalAPI" threetoken="true">https://api-3t.paypal.com/2.0/</port>
          <port name="PayPalAPIAA" threetoken="true">https://api-aa-3t.paypal.com/2.0/</port>
        </environment>
        <environment name="sandbox">
          <port name="PayPalAPI">https://api.sandbox.paypal.com/2.0/</port>
          <port name="PayPalAPIAA">https://api-aa.sandbox.paypal.com/2.0/</port>
          <port name="PayPalAPI" threetoken="true">https://api-3t.sandbox.paypal.com/2.0/</port>
          <port name="PayPalAPIAA" threetoken="true">https://api-3t.sandbox.paypal.com/2.0/</port>
        </environment>
      </wsdl>
    </endpoints>
  </paypal>

After i ran my test app i didn't receive the error anymore.

The following was returned by the service. As you can see the Tls12 is used.

 

Encrypted HTTPS traffic flows through this CONNECT tunnel. HTTPS Decryption is enabled in Fiddler, so decrypted sessions running in this tunnel will be shown in the Web Sessions list.

Secure Protocol: Tls12
Cipher: Aes256 256bits
Hash Algorithm: Sha256 256bits
Key Exchange: RsaKeyX 2048bits

== Server Certificate ==========
[Subject]
  CN=api-3t.sandbox.paypal.com, OU=PayPal Production, O="PayPal, Inc.", L=San Jose, S=California, C=US

[Issuer]
  CN=Symantec Class 3 Secure Server CA - G4, OU=Symantec Trust Network, O=Symantec Corporation, C=US

[Serial Number]
  217F365CBC607A4D1EBCAAC64F0E53C0

[Not Before]
  11/16/2017 4:00:00 PM

[Not After]
  1/14/2020 3:59:59 PM

[Thumbprint]
  E6080088F108EE1EE3659CCE1CB022BDDCEB535A

[SubjectAltNames]
api-3t.sandbox.paypal.com

I'm not exactly sure why 'https://api-3t.sandbox.paypal.com/2.0/' is used without the config but it works and i'm happy.

 

Another thing to note is that the 'ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12' setting doesn't have an affect. The response works without it, however, i'm keeping it, just in case.

 

I'll attach my code to this thread.

 

 

Login to Me Too

abs321
Contributor
Contributor
Please note that the ack will return an error but it proves that the service was called.
var apiUsername = "TODO";
var apiPassword = "TODO";
var signature = "TODO";

var address = new Address
{
    FirstName = "TODO",
    LastName = "TODO",
    Street1 = "TODO",
    City = "TODO",
    StateCode = "TODO",
    PostalCode = "TODO",
    CountryCode = "US"
};

var isTestMode = true;
var creditCardNumber = "TODO";
var creditCardType = CreditCardTypeType.Visa;
var creditCardExp = "04/2025";
var cvv = "TODO";
var orderTotal = 1;

ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

var caller = new CallerServices();
var iAPIProfile = ProfileFactory.CreateAPIProfile();
iAPIProfile.APIUsername = apiUsername;
iAPIProfile.APIPassword = apiPassword;
iAPIProfile.APISignature = signature;
iAPIProfile.Subject = string.Empty;
if (!isTestMode)
{
    iAPIProfile.Environment = "live";
}
caller.APIProfile = iAPIProfile;

var doDirectPaymentRequestType = new DoDirectPaymentRequestType();
var pd = new DoDirectPaymentRequestDetailsType();
var cc = new CreditCardDetailsType();
var dt = new PaymentDetailsType();
cc.CardOwner = new PayerInfoType();
cc.CardOwner.Address = new AddressType();
cc.CardOwner.PayerName = new PersonNameType();
dt.OrderTotal = new BasicAmountType();

doDirectPaymentRequestType.DoDirectPaymentRequestDetails = pd;
pd.CreditCard = cc;
pd.PaymentDetails = dt;

pd.IPAddress = "127.0.0.1";
pd.MerchantSessionId = Guid.NewGuid().ToString();
pd.PaymentAction = PaymentActionCodeType.Sale;
cc.CreditCardNumber = creditCardNumber;
cc.CreditCardType = creditCardType;
cc.CVV2 = cvv;
var array = creditCardExp.Split('/');
cc.ExpMonth = int.Parse(array[0]);
cc.ExpYear = int.Parse(array[1]);
cc.CardOwner.Payer = address.EmailId;
cc.CardOwner.PayerID = "";
cc.CardOwner.Address.Street1 = address.Street1;
cc.CardOwner.Address.Street2 = address.Street2;
cc.CardOwner.Address.CityName = address.City;
cc.CardOwner.Address.StateOrProvince = address.StateCode;
cc.CardOwner.Address.PostalCode = address.PostalCode;
cc.CardOwner.Address.CountryName = address.CountryCode;
cc.CardOwner.Address.Country = (CountryCodeType)Enum.Parse(typeof(CountryCodeType), address.CountryCode);
cc.CardOwner.Address.CountrySpecified = true;
cc.CardOwner.PayerName.FirstName = address.FirstName;
cc.CardOwner.PayerName.LastName = address.LastName;
dt.OrderTotal.currencyID = CurrencyCodeType.USD;
dt.OrderTotal.Value = orderTotal.ToString();
var doDirectPaymentResponseType = (DoDirectPaymentResponseType)caller.Call("DoDirectPayment", doDirectPaymentRequestType); var ack = doDirectPaymentResponseType.Ack; Console.WriteLine(doDirectPaymentResponseType.Ack);
Login to Me Too

dedvalson
Contributor
Contributor

abs321's hints fixed it form me. THANKS!!

Login to Me Too

Haven't Found your Answer?

It happens. Hit the "Login to Ask the community" button to create a question for the PayPal community.