bender

bender

HTTPS request with HTTPoison

Hello.

I spent a day trying manage this wall, but didn’t successed. When I send a request it ends up with an error:

** (HTTPoison.Error) {:tls_alert, {:handshake_failure, 'TLS client: In state hello received SERVER ALERT: Fatal - Handshake Failure\n'}}
    (httpoison 1.8.0) lib/httpoison.ex:156: HTTPoison.request!/5

The same problem is described here HTTPS handshake error: Fatal - Handshake Failure - #11 by rjk but solution didn’t help.

Here is my code:

    rsa_kx = :ssl.cipher_suites(:all, :"tlsv1.2") ++ [%{key_exchange: :rsa, cipher: :aes_256_cbc, mac: :sha256}]

    HTTPoison.get!("https://etpgpb.ru/procedures.json", [],
      ssl: [
        ciphers: rsa_kx,
        verify: :verify_peer,
        cacertfile: :certifi.cacertfile(),
        depth: 3,
        customize_hostname_check: [
          match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
        ]
      ],
      log_level: :debug
    )

Also some details from nmap and curl.

nmap:

PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   TLSv1.0: 
|     ciphers: 
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|     compressors: 
|       NULL
|     cipher preference: server
|     warnings: 
|       Forward Secrecy not supported by any cipher
|   TLSv1.1: 
|     ciphers: 
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|     compressors: 
|       NULL
|     cipher preference: server
|     warnings: 
|       Forward Secrecy not supported by any cipher
|   TLSv1.2: 
|     ciphers: 
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|     compressors: 
|       NULL
|     cipher preference: server
|     warnings: 
|       Forward Secrecy not supported by any cipher
|_  least strength: A

curl:

* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / AES128-SHA

Marked As Solved

voltone

voltone

The server only supports TLS_RSA_WITH_AES_128_CBC_SHA and TLS_RSA_WITH_AES_256_CBC_SHA, which in :ssl terms would be:

iex(1)> supported = Enum.map(['TLS_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_AES_256_CBC_SHA'], &:ssl.str_to_suite/1)
[                                                           
  %{cipher: :aes_128_cbc, key_exchange: :rsa, mac: :sha, prf: :default_prf},
  %{cipher: :aes_256_cbc, key_exchange: :rsa, mac: :sha, prf: :default_prf}
]

Not only are those cipher suites not enabled by default, they are not supported by :ssl unless you explicitly downgrade the TLS version to 1.1. If a newer version of TLS is active, the initial handshake message to the server will optimistically try to negotiate the newest version, and it won’t offer those old (deprecated) cipher suites.

So after running the above, this will work (using :hackney_ssl.check_hostname_opts/1 to ensure all the other options are set correctly):

iex(2)> check_hostname_opts = :hackney_ssl.check_hostname_opts('etpgpb.ru')
# ...
iex(3)> ssl_opts = Keyword.merge(check_hostname_opts, ciphers: supported, versions: [:"tlsv1.1"])
# ...
iex(3)> HTTPoison.get!("https://etpgpb.ru/procedures.json", [], ssl: ssl_opts)
%HTTPoison.Response{
  #...
  status_code: 200
}

Where Next?

Popular in Questions Top

hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New

Other popular topics Top

baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49134 226
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement