4

We are developing a web page that use https protocol (two way).

We need to access to the private certificates of the user, because we need sign documents by the user's certificate, so we developed a Java application that communicate with the web by a websoket.

This application will call with a protocol call since the web (same that when you open a pdf on Acrobat Reader from a browser).

So we have to be sure that our web is calling to the native application(only our web). We want develop a system to be sure of that. Our idea:

  1. Send a public key, a signed token by the server's private certificate and a symmetric key (to encrypt websocket communications) to the native application.
  2. Next, we will Check in the native application that the token it is OK with a web service to the server.
  3. After, we will have to open the websocket between the native app and the web, and send the signed document by the native app by this way.
  4. Then sent document to the server.

Is this implementation safe? We will be safe of a man in the middle?

Any suggestion about this solution will be wellcome, because I don't see any weakness but I am not an expert on security.

I know other solutions for this problem, like applets, JavaFX or native messages on Chrome, but I only want to know if these solution is safe.

Thanks to all in advance and sorry if my english isn't the best :P,

Betwen
  • 145
  • 11
  • At present WebCryptoAPI does not have way to access local certificate store (or smartcard/usb token). For digital signing from modern browsers, please refer to [SO Answer](https://stackoverflow.com/a/55676351/9659885) – Bharat Vasant Oct 02 '20 at 00:59

1 Answers1

1

I see the following issues

  1. Send a public key and a signed token by the server's private certificate to the native application.

You are calling a local app by protocol. For example mylocalapp://sign?securitytoken=.... You do not control which application is installed on local PC to respond to mylocalapp://. The browser shows an ugly warning because you are leaving the secure environment. An attacker could have replaced the default app, simulate the flow and get all signed documents.

2.Next, we will Check in the native application that the token it is OK with a web service to the server.

To verify identity of server and avoid a ManInTheMiddel attach you need also to set a trustore for your application with the server certificate

Your server needs also to verify identity of client. Are you planning to use TLS two ways also?

  1. After, we will have to open the websocket between the native app and the web, and send the signed document by the native app by this way.

You do not need a websocket. Simply use a URL connection to download and upload the documents.


This solution was used by Spanish ministry of economy when chrome decided to cut the NPAPI support and signature applets began to fail. Now, they have rebuilt the system in this way

  1. Install a local Java application on the user's PC. The application listens on a port as, for example 5678

  2. In your page, javascript connects to the application in the form http://127.0.0.1:5678/sign and sends the data to sign.

  3. The application is local and has no trouble using the operating system keystore, which includes drivers PKCS#11. Perform digital signature and sends the result to the server

  4. The javascript of the page periodically query the result and retrieves it when ready

The security problem is basically the same, but install a server in localhost is harder than replace the local default app.

The solution is called @firma, I guess you probably know it. It is opensource, you can use it

pedrofb
  • 37,271
  • 5
  • 94
  • 142
  • You are right, I know "@"firma, and the option that you are talking on the last part of your post is the old option that "@"firma give for the problem that I have. In a personal meeting with the "@"firma team, they reconice to me, that it'snt a good option. Imagine hundred of users accessing to the web and periodically query for the result... – Betwen Jul 29 '16 at 13:45
  • Now they have a solution with sockets. 1-I think that you could only execute a Java signed application by a security organization(if you configure it). 2-Yes we use TLS two ways, and trustore 3-Could you explain more this point? I really like your answer because confirm some of my Doubts – Betwen Jul 29 '16 at 14:03
  • 1) In fact, you can execute any application registered to protocol in Windows Registry 3) A WebSocket is useful to maintain an active connection open, ant allow server to send data to the client. In your case, the local app first downloads the document from server, and after signed, uploads it, so I think you just need a Java URLConnection to Post data. You would need a websocket if you install the local application as a server, like in the example I have provided. The page opens a websocket to the application and is called back when user finish signature – pedrofb Aug 01 '16 at 06:28
  • Alternatively, if you work in a controlled environment and with software certificates, you might consider using the WebCryptographyApi for signature without leaving the browser – pedrofb Aug 01 '16 at 06:30