Fleck: Error in Secure Websocket

Hello,

i need your help, i’m using your console app sample to test secure WebSockets (wss) i did changes to your code as below:

console cs: var server = new WebSocketServer(“wss://127.0.0.1:2080”); server.Certificate = new X509Certificate2(@“[path]\beaweb.cert.pfx”, “password”);

client.html: window.ws = new wsImpl(‘wss://127.0.0.1:2080/’);

i have used openssl to generate my certificate:

  1. openssl req -x509 -days 1460 -newkey rsa:2048 -keyout beaweb.key.pem -out beaweb.cert.pem pwd: [password]

  2. openssl pkcs12 -export -in beaweb.cert.pem -inkey beaweb.key.pem -out beaweb.cert.pfx pwd: [password]

  3. openssl pkcs12 -in beaweb.cert.pfx -clcerts -nokeys -out beaweb.cert.public.pem pwd: [password]

when i tried to run your sample after this i got the below exception:

2/6/2018 3:55:40 PM [Info] Server started at wss://127.0.0.1:2080 (actual port 2080) 2/6/2018 3:55:40 PM [Debug] Using default TLS 1.0 security protocol. 2/6/2018 3:55:55 PM [Debug] Client connected from 127.0.0.1:10953 2/6/2018 3:55:55 PM [Debug] Authenticating Secure Connection 2/6/2018 3:55:55 PM [Warn] Failed to Authenticate System.AggregateException: One or more errors occurred. —> System.IO.IOException: Authentication failed because the remote party has closed the transport stream. at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result) at System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult asyncResult) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization) — End of inner exception stack trace — —> (Inner Exception #0) System.IO.IOException: Authentication failed because the remote party has closed the transport stream. at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result) at System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult asyncResult) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization)<—

i need to know if i missed something, i need your help because i built mvc web application communicating to client hardware like camera, fingerprint and passport reader using your library, it’s working fine when i running my site as http, but it faild when i switch to https!

thank you

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 17

Most upvoted comments

Everyone seems to have a different way of generating these certificates & 99% never seem to work. So here goes with how I get it to work…

This will create an ssl certificate using test.com to test secure WebSockets in your local environment.

Install Win32 OpenSSL v1.1.0g from https://slproweb.com/products/Win32OpenSSL.html

Save below as openssl.cnf to C:\OpenSSL-Win32\

[ req ]
default_bits        = 2048
default_keyfile     = server-key.pem
distinguished_name  = subject
req_extensions      = req_ext
x509_extensions     = x509_ext
string_mask         = utf8only

# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
#   Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
[ subject ]
countryName         = Country Name (2 letter code)
countryName_default     = US

stateOrProvinceName     = State or Province Name (full name)
stateOrProvinceName_default = NY

localityName            = Locality Name (eg, city)
localityName_default        = New York

organizationName         = Organization Name (eg, company)
organizationName_default    = Example, LLC

# Use a friendly name here because its presented to the user. The server's DNS
#   names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
#   by both IETF and CA/Browser Forums. If you place a DNS name here, then you 
#   must include the DNS name in the SAN too (otherwise, Chrome and others that
#   strictly follow the CA/Browser Baseline Requirements will fail).
commonName          = Common Name (e.g. server FQDN or YOUR name)
commonName_default      = Example Company

emailAddress            = Email Address
emailAddress_default        = test@test.com

# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]

subjectKeyIdentifier        = hash
authorityKeyIdentifier  = keyid,issuer

# You only need digitalSignature below. *If* you don't allow
#   RSA Key transport (i.e., you use ephemeral cipher suites), then
#   omit keyEncipherment because that's key transport.
basicConstraints        = CA:FALSE
keyUsage            = digitalSignature, keyEncipherment
subjectAltName          = @alternate_names
nsComment           = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
#   In either case, you probably only need serverAuth.
# extendedKeyUsage  = serverAuth, clientAuth

# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
[ req_ext ]

subjectKeyIdentifier        = hash

basicConstraints        = CA:FALSE
keyUsage            = digitalSignature, keyEncipherment
subjectAltName          = @alternate_names
nsComment           = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
#   In either case, you probably only need serverAuth.
# extendedKeyUsage  = serverAuth, clientAuth

[ alternate_names ]

DNS.1       = test.com
DNS.2       = www.test.com
DNS.3       = mail.test.com
DNS.4       = ftp.test.com

# Add these if you need them. But usually you don't want them or
#   need them in production. You may need them for development.
# DNS.5       = localhost
# DNS.6       = localhost.localdomain
# DNS.7       = 127.0.0.1

# IPv6 localhost
# DNS.8     = ::1

open cmd

run: cd "c:\OpenSSL-Win32\bin"

run: set OPENSSL_CONF=c:\OpenSSL-Win32\openssl.cnf

run: openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout test.key -out test.crt -subj "/CN=test.com" -days 3650

Import “test.crt” into certificate store:

  1. Open certlm.msc
  2. Go to Trusted Root Certificate Autorities > Certificates
  3. Right-click somewhere, select All Tasks > Import
  4. Browse for the file test.crt just created (will be in C:\OpenSSL-Win32\bin)
  5. Select Place all certificates in the following store: Trusted Root Certification Authorities
  6. Click Finish

Export this certificate from the store:

  1. Refresh the Trusted Root Certificate Authorities > Certificates, locate & right-click the test.com certificate
  2. Select All Tasks > Export
  3. Export as test.p7b & save it in C:\OpenSSL-Win32\bin\
  4. Delete test.com certificate that’s currently in cert store

run: openssl pkcs7 -in test.p7b -inform DER -out result.pem -print_certs

run: openssl pkcs12 -export -inkey test.key -in result.pem -name test.com -out final_result.pfx

Import “final_result.pfx” into the certificate store:

  1. Double-click the generated final_result.pfx file to run the installer
  2. Select local machine
  3. Enter the password
  4. Select mark this key exportable
  5. Select include all extended properties
  6. Select place all certificates in the following store: Trusted Root Certification Authorities
  7. Click Finish

Repeat above import steps 1 to 7 again, but this time in step 6, place the certificate in the “Web Hosting” certificate store (so that IIS can see the certificate when binding to https)

Export this certificate from the store (to use in the socket server app):

  1. Refresh the Trusted Root Certificate Authorities > Certificates, locate & right-click the test.com certificate
  2. Select All Tasks > Export
  3. Select yes, export private key
  4. Select Personal Information Exchange
  5. Select include all certificates if possible
  6. Select export all extended properties
  7. Select enable certificate privacy
  8. Add password
  9. Add filename test.com.pfx (save it to C:\ or the location where your “socket server app” will reference it, see below) X509Certificate2 certificate = new X509Certificate2("C:\\test.com.pfx", "password");

Add test.com to host file along with local pc ip

Create IIS website & add bindings to test.com for both http & https (and select the test.com certificate in the https bindings)

Visit https://test.com/your-socket-client.htm (in Chrome/Edge, click advanced > proceed when prompted for ssl warning)

Socket client should now connect successfully over wss using wss://test.com:xxxx