2016-04-18 7 views
0

Я создал сертификат в каталоге моего приложения Haskell:Ошибка «пустая цепочка сертификатов» в базовой Haskell приложении

openssl genrsa -out key.pem 2048 
openssl req -new -key key.pem -out certificate.csr 
openssl x509 -req -in certificate.csr -signkey key.pem -out certificate.pem 

, и тогда я побежал мое приложение:

import Network.Wai 
import Network.Wai.Handler.Warp 
import Servant 
import Network.Wai.Handler.WarpTLS 

startApp :: IO() 
startApp = do 
    let port = 3345 
    let tls = tlsSettings "certificate.csr" "key.pem" 
    runTLS tls (setPort port defaultSettings) app 

А потом пошла до https://localhost:3345 и я получил сообщение об ошибке «пустая цепочка сертификатов»

Что в этом плохого? Может быть, я поставил свой сертификат где-нибудь, например «/ opt/....»?

На данный момент все 3 файла находятся в корневом каталоге моего приложения: key.pem, certificate.csr и certificate.pem.

UPDATE:

Это Arch Linux, в то время как на хостинг у меня есть Ubuntu, поэтому мне нужно решение для обеих сторон.

Этот сертификат является самоподписанным, тогда как на хостинге он выдается путем шифрования.

Я изменил код, немного: "Csr" в PEM:

let tls = tlsSettings "certificate.pem" "key.pem" 
runTLS tls (setPort port defaultSettings) app 

Вот еще одна ошибка:

$ curl -v https://localhost:3345 
* Rebuilt URL to: https://localhost:3345/ 
* Trying ::1... 
* connect to ::1 port 3345 failed: Connection refused 
* Trying 127.0.0.1... 
* Connected to localhost (127.0.0.1) port 3345 (#0) 
* ALPN, offering http/1.1 
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH 
* successfully set certificate verify locations: 
* CAfile: /etc/ssl/certs/ca-certificates.crt 
    CApath: none 
* TLSv1.2 (OUT), TLS header, Certificate Status (22): 
* 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 (OUT), TLS alert, Server hello (2): 
* SSL certificate problem: self signed certificate 
* Closing connection 0 
* TLSv1.2 (OUT), TLS alert, Client hello (1): 
curl: (60) SSL certificate problem: self signed certificate 
More details here: https://curl.haxx.se/docs/sslcerts.html 

curl performs SSL certificate verification by default, using a "bundle" 
of Certificate Authority (CA) public keys (CA certs). If the default 
bundle file isn't adequate, you can specify an alternate file 
using the --cacert option. 
If this HTTPS server uses a certificate signed by a CA represented in 
the bundle, the certificate verification probably failed due to a 
problem with the certificate (it might be expired, or the name might 
not match the domain name in the URL). 
If you'd like to turn off curl's verification of the certificate, use 
the -k (or --insecure) option. 
+0

Вы получаете сообщение об ошибке в своем приложении или это браузер, информирующий вас о том, что сертификат может быть не доверен? - Потому что, если я проверю [код] (https://hackage.haskell.org/package/tls-1.3.3/docs/src/Network-TLS-Credentials.html#credentialLoadX509Chain), который должен использоваться здесь (ну, я только быстрый взгляд и текущие документы не на * hackage *, поэтому я совсем не уверен) - кажется, что единственная ошибка, которую вы должны получить, это '' никакие ключи не найдены '' - можете ли вы разместить фактический вывод? – Carsten

+0

Возможно, вы захотите попробовать [MouseBox] (https://github.com/shimmercat/mousebox) .... – dsign

+0

@Carsten, это результат моего приложения, там больше ничего нет. – Jushiti

ответ

3

TL; DR: Обработка сертификатов трудно. Используйте самозаверяющий файл .pem (и ключ) и добавьте исключения безопасности в ваш браузер или вашу операционную систему. Файл .csr - это не то, что вы можете использовать. Сервер отлично (за исключением файла .csr), но вы получите предупреждения о безопасности, пока не получите свой ключ, подписанный ЦС (что невозможно для локальных доменных имен).


What's wrong with it?

Сервер (почти) отлично. Однако вы хотите отправить файл .pem. .csr является запросом для подписания вашего сертификата органом сертификации (ЦС). CA необходимо доверять пользователю или другому CA (которому доверяет пользователь). Давайте посмотрим на ваши оригинальные команды:

openssl genrsa -out key.pem 2048 

Это произведет the private key, который привыкнет для рукопожатия TLS и других операций.

openssl req -new -key key.pem -out certificate.csr 

Это будет генерировать упомянутые certificate sigining request. Вы отправите этот запрос в центр сертификации, который проверяет вашу личность. Например, они будут проверять, действительно ли FQDN принадлежит вам. В противном случае вы можете запросить сертификат для stackoverflow.com и использовать атаку MITM. Это также делает вывод о том, что вы не можете запросить (нелокальный) ЦС сертификат на локальное имя, например localhost или hostname.local.domain.name.

openssl x509 -req -in certificate.csr -signkey key.pem -out certificate.pem 

Это займет первоначальный запрос сертификата, используйте ключ собственного подписать его и создать сертификат (certificate.pem). Обычно этот сертификат содержит цепочку CA, например.который подписал сертификат CA, который подписал сертификат того, кто подписал сертификат CA и т. д., пока мы не закончим с корневым сертификатом.

Итак, все, что вам нужно сделать, это использовать , чтобы сертификат вместе с вашим личным ключом. Это приведет к предупреждению о безопасности, поскольку вы не можете подтвердить свою личность. Вот почему вам нужно --insecure в curl и исключение безопасности в большинстве браузеров. В стороне это будет работать. Обратите внимание, что сервер не знает, что его сертификат самоподписан. Это просто использование двух файлов для инициирования связи с клиентом.

 Смежные вопросы

  • Нет связанных вопросов^_^