We are building a Java website to share documents with users.
Once a user access to his documents, he can digitally sign them with his certificate (It is stored on client-side).
The requirement is an on-line sign with a “sign button” on the documents list.
We researched ways to accomplish the requirement but apparently, there is not a way to do that without using Java Applet or a secured server that contains the users certificates.
We know what other solution would be use Itext on a stand-alone Java Application but that is not an online solution.
The question is:
Is there a way to access to the user's key-store or load the certificate from the file system on the sign process without use an applet?
Thanks and regards.
It is not possible to use a certificate installed on system/browser keystore using javascript due to security restrictions
An alternative solution is to install on the client an application with an embedded web server and send the document from the webpage to be signed at the moment. This application can use the keystore and include the itext library.
If the user has a certificate file (.p12/.pfx) it is possible to load the content using WebCryptographyApi and sign the document in client side (without uploading certificate to server. See How to load a PKCS#12 Digital Certificate with Javascript WebCrypto API
#pedrofb is right, you won't, without the help of a plug-in, be able to access the certificate store on the host.
You can in browser use WebCrypto with a library like PKIjs load a key into the browser and sign with it, you can also verify the PDFs signature if you like. Here are some related examples:
https://pkijs.org/examples/PDFexample.html
https://pkijs.org/examples/PKCS12SimpleExample.html
https://pkijs.org/examples/PKCS10_complex_example.html
http://unmitigatedrisk.com/?p=543
You can see https://hwcrypto.github.io/ for a discussion, and plug-ins that provide access to smart cards within the browser.
Modern browsers does not support applets. For browser based signing scenarios, my company has published free Chrome extension Signer.Digital and setup may be downloaded from cNet using link https://download.cnet.com/Signer-Digital-Chrome-Extension/3000-33362_4-78042540.html
Installing this host and restarting Chrome will automatically add Signer.Digital Chrome Extension
Javascript to call method from extension:
//Calculate Sign for the Hash by Calling function from Extension SignerDigital
SignerDigital.signPdfHash(hash, $("#CertThumbPrint").val(), "SHA-256") //or "SHA256"
.then(
function (signDataResp) {
//Send signDataResp to Server
},
function (errmsg) {
//Send errmsg to server or display the result in browser.
}
);
If Failed, returns error msg starting with "SDHost Error:"
If success, returns Base64 encoded pkcs7 signature - as you said, use iText or any suitable library to inject sign to pdf.
Disclosure: I work for CISPL (Signer.Digital)
Related
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:
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.
Next, we will Check in the native application that the token it is OK with a web service to the server.
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.
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,
I see the following issues
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?
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
Install a local Java application on the user's PC. The application listens on a port as, for example 5678
In your page, javascript connects to the application in the form http://127.0.0.1:5678/sign and sends the data to sign.
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
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
I am working on allowing a chrome extension to post a new entry to my site via post data.
I want to be able to lock it down so only the chrome extension can post. If I get post data from anywhere else I want to reject it.
Does anyone know if/how this is possible or how you would go about doing it?
Unfortunately, validating clients (whether a Chrome extension, an Android app, an iOS app, client-side JavaScript, or some other client) from a web server is an unsolved problem.
There are some things that you can do to deter abuse and mitigate this problem such as:
Requiring user authentication (and rate-limiting usage per-user)
Rate-limiting access on the basis of IP addresses
Requiring tokens to be provided that are handed out in prior requests (this can be used to ensure that certain APIs are called in certain expected orders / patterns).
Showing a CAPTCHA or other challenge for anomolous or over-limit usage
While you can additionally check things such as user agent, referrer URL, or a token that you embed in the Chrome extension, with any distributed application, it is easy to reverse-engineer these and mimick them in a counterfeit app, and so these aren't true solutions.
You can add a simple check in the code.
Following code stops anyone who is trying to access your api outside the chrome extension.
if(substr($_SERVER['HTTP_ORIGIN'],0,19) !== "chrome-extension://") die("Not Allowed")
Easy Privacy In the past, securely storing and transferring
confidential information required the installation of dedicated
software. The new Mega encrypts and decrypts your data transparently
in your browser, on the fly. You hold the keys to what you store in
the cloud, not us.
This quote is taken from the website of the new MegaUpload filehosting service, which is sheduled to be launched on jan 19th this month.
Naturally as a web-developer I am interested and curious about the technology behind.
All I could find were screenshots and claims, that make it seem authentic, that the data is really never leaving the client unencrypted!
Files and transfers are secured using AES.
Every client gets an asymmetric key-pair, I can only guess why, but I think it will be used to encrypt the AES initialisation vector and key for other clients of which you want to share the file with.
However my question is this:
How is it technically possible to intercept the file upload/download?
I know there are encrpytion algorithms for both RSA and AES that run in javascript and are very efficient.
But the only browser which seems to have support for operating within the file system is chrome.
How does the data get from the harddrive to the clients browser to be encrypted? And how does it get from there to a file on the hard drive?
I do not know about such a thing as a filesystem API. Even html5 supports only some sort of object storage.
I guess its pretty trivial with some sorts of browser plugins or maby a java or adobe air applet, but they claim that there will be no such things as 3rd party software that needs to be installed.
Is there another way?
How is it technically possible to intercept the file upload/download?
You don't intercept it. The user picks a file (or files) using an <input type="file"> element, then JavaScript reads the value of the file input and encrypts it. The upload will probably be done via Ajax.
But the only browser which seems to have support for operating within the file system is chrome.
Chrome is the first to implement the filesystem API, which is different from the file API. The filesystem API manages a sandboxed filesystem (not the user's true OS filesystem); the file API reads files from <input type="file"> elements. The file API has much broader support (but not perfect support) in most modern browsers.
For encryption and upload, JavaScript can read files which the users specifically selects using a file input and send the encrypted value to the server via Ajax. For download, the browser can perform an Ajax fetch of the resource, decrypt it, and prompt the user to save the file (e.g., by redirecting to a data: URI). No programmatic access to the filesystem is necessary.
Recently received a request to add communication to a device connected via serialport on the client's machine through my webpage.
I'd done some googling and found that node.js with node-serialport seems to be the javascript way of doing it. However, in my case, the device is actually connected to the client's machine, and not the server.
My question would be how do i implement node.js in this sense? Since the code is run at the client browser, is it possible for me to 'embed' node.js on my webpage?
Or is there any other alternative for doing this? Applet and ActiveX are out of the picture though.
Thanks
UPDATES:
Had managed to convince the client to have applet loaded from the web, so we'll be going through the applet route. Thanks all for your great info! =)
JavaScript in the browser only has access to the APIs provided by the browser: it lives in the browser sandbox where it (rightly) has no access to the client file system or other hardware.
This is different from node.js, which is a server implementation that has access to all sorts of other file system APIs.
To "break out" of the browser you must use some sort of browser extension.
You will have to create a plugin, an applet, or a client side application to get the data into the client's web browser before being sent off to your server.
You could make a small app that reads the serial port of the clients machine that creates a .js file, and then your web page includes that src of that "dynamically" created js file on the client's machine and presto your webpage gets access to the serial port in a roundabout way.
This is how GPSGate works: http://gpsgate.com/developer/gps_in_browser/
See also here: How to read from Serial port in a webpage
And a java applet based solution:
http://code.google.com/p/java-simple-serial-connector/
http://code.google.com/p/java-simple-serial-connector/wiki/jSSC_Terminal
Try app.js if you want to access node.js functions from browser.
This can only be done via Active X or a plugin like Java or Flash. Code in JavaScript is only as powerful as the APIs provided to it from the browser.
Want to sent an HTTP request to a server? JavaScript can do that (subject to the same-origin policy), because the browser has the XMLHttpRequest API. Want to query what processes are running on the operating system right now? JavaScript cannot do that, because no browser provides an API for querying the OS about what processes it is running.
No browser that I know of implements any kind of JavaScript API for performing serial port operations, so there is no way to do it without using a plugin.
However, this does not preclude the possibility of such an API existing someday: the getUserMedia function can grab data from a camera or microphone, and it could theoretically be expanded to get data from other devices as well.
Another option (other than ActiveX or Java applet with security permissions) might be Google Native Client and the Pepper API, though whether this would be sufficient to access a serial port, I do not know.
A Firefox extension can include a native XPCOM component that could access the serial port, and you might find there is already a way to access the serial port from browser chrome (which extensions are) because the security token and smartcard system supports serial readers. A Firefox extension could also be used to deliver the next solution, which requires placing a native component or application on the system.
Can you tell us what browser(s) and OS('s) are targetted here, and why ActiveX and Java are ruled out?
Others have suggested a native running proxy exposing the serial port through some protocol. You could use node for this, or python, or any other language that can create both a serial connection and a socket. To access the proxy from a browser application you would need special security permissions to be granted to the page, and then you can make your proxy an HTTP or WebSocket server. You can also serve javascript from the proxy which would grant the script HTTP and WebSocket access to it's origin server which is the proxy. Google Chrome extensions can access any destination and port with their socket client. Also, I believe a config can be set in Google Chrome to allow this for certain or every page, the same with allowing native client to be used by a webpage.
Without knowing more about your goal, I can't determine what the best solution would be.
Another option to read the serial port data is using sockjs and sockjs-client-node at the server side and sockjs-0.3.js at the client side.
I have a got a file server and a web server. They are running on physically different machines.
I would like to download a file from the FTP server via JavaScript. The reason I have to do it via JavaScript is that I have an external application and I can only inject JavaScript into that application.
Basically, I need to specify ftp address username and password. But I am concerning about security as people can view FTP credentials.
What is the best way to implement such scenario?
Thanks for your help
Regards
Javascript only speaks HTTP and WebSockets (on newer browsers), and not FTP. In that situation, keeping it all on the client-side, you'd probably have to write a Flash or Java applet that handles the actual FTP protocol, and interface with Javascript to provide interactivity.
Unless you're planning on redirecting the browser to the ftp site, passing in the username and password? Are you concerned about the users getting the FTP information, or are you concerned with man-in-the-middle attacks sniffing the plaintext FTP credentials?
JavaScript doesn't support FTP. What you need is a server-side or a more robust client-side language to access the remote server.
If by "downloading" you mean "prompt user to save a file from external link" (which basically means open a new window with URL that points to a file) then you can just point user to a script you have control over.
window.open('http://myserver/get_file/filename');
And your server-side get_file script will do all the work of connecting to a FTP and fetching a file
How about creating an iframe and setting the url to ftp://whatever?