I know, it looks strange, but I need to sign some data on client-side using javascript only, no ajax backdoor to server-side openssl available. Could someone suggest some client-side solution to sign data using private key? Is it possible?
Thanks.
Found great signing tool. It implements RSA-SHA1 (works perfectly) and RSA-SHA256 (works strange), and allow both to generate signature using private key and to verify signature using certificate.
I've gone down the same road as you, you're probably better off implementing something like oAuth.
The problem with what you're proposing is that there's absolutely no reliable way of storing the private key on the client machine, nor of now securely getting the public key back to the server other than HTTPS (and if you're using HTTPS, what's the point of this?)
If you really want to continue, there are some implementations out there: http://shop-js.sourceforge.net/crypto2.htm
And you probably want something horribly annoying like PersistJS (http://pablotron.org/?cid=1557) to try and save the private key as long as possible.
The W3C Web Cryptography API may be able to help. Can I use indicates modern browsers now support it.
For additional digital signature support, look at GlobalSign/PKI.js
PKIjs is a pure JavaScript library implementing the formats that are
used in PKI applications (signing, encryption, certificate requests,
OCSP and TSP requests/responses). It is built on WebCrypto (Web
Cryptography API) and requires no plug-ins. http://pkijs.org
Web Crypto appears to be the answer. Here is a tutorial (not mine). As for the comment, if you are using https, why do you need signing - these are needed for two different purposes. In infosec lingo, the former gives confidentiality and the latter non-repudiation.
Related
I wrote a little webapp for secure message transfer to learn more about encryption, and wanted to show it to my friends and let them play with it a little, so I hosted it on my little server, and was shocked to find that the Web Crypto API (which I worked my ass off to get to work because it is not very specific in its error messages) REQUIRES SSL ( kinda defeats the purpouse of implementing your own encryption scheme in browsers)!
I already have another API running on that server with SSL, but instead of merging them I wanted to ask: Is there a way to circumvent the secure socket requirement of Web Crypto API, or is there another library out there which allows me to use the same or similar functions in a non-secure context?
The WebCrypto API specification(https://www.w3.org/TR/WebCryptoAPI/ ) does not restrict to SSL, but browser implementations require a "secure origin"
For example, Chrome requires https , wss, localhost or an extension. See https://stackoverflow.com/a/46671627/6371459
You would need to set up a SSL connection in order to use webcrypto. If you want to use another library (forge, pki.js, etc.) you will not have this restriction, although it is advisable to use SSL / TLS when using cryptography.
Although I haven't tried this, you could use a shim. https://github.com/vibornoff/webcrypto-shim
A shim is a javascript file that does the same thing as the built-in method.
It's used for older browsers that don't support the new methods.
I'm wondering if it would be best practice to use a clients fingerprint as JWT-secret for encoding. However I couldn't find anything in the WWW concerning this question, but so far it makes sense to me to do it.
I'm thinking about generating a fingerprint client-side with JavaScript and sent it to the API with every call. The API should then use the fingerprint with a hard coded secret together for encoding and decoding the token.
Isn't this a good method to prevent CSRF?
Or am I missing out on something else?
Or in general: What is the best way to prevent CSRF with JWT?
(I'm using PHP and VueJS, is there maybe a case related solution?)
I have never heard about that.
A token is signed using a private key or a shared secret. The use of a fingerprint means you can correlate one (or more) fingers to a private key then compute a token.
However, this looks very similar to the Webauthn protocol I am working with. When using Android devices, the browser can interact with the fingerprint/screenlock to authenticate the user. The data sent by the device is a JWT that can be verified using a Google API (see Android SafetyNet).
I am building a service which is using a powerful client-side script to execute actions. All communications with a server are done via WebSockets. I am looking for a way to protect information which is transferring between server and client, so nobody with beginning/medium knowledge in Chrome debugging and HTTP scrapping can simply decode these data. The script itself will be deeply obfuscated.
I read there are some RSA libraries for javascript to encrypt/decrypt data, but I hear like RSA is old and slow and that's why I need someone's advice who is the guru in such things. I need for simple MIT library, no need for paid solutions and giant-sized packages.
I am looking for a way to protect information which is transferring between server and client,
That is SSL (https) for. There is no reason not to use SSL
so nobody with beginning/medium knowledge in Chrome debugging and HTTP scrapping can simply decode these data. The script itself will be deeply obfuscated.
Often it is not so effective. If data are user entered or displayed, there is no reason to encrypt them. If data are provided from the server and not to be displayed, you can encrypt the data properly on the server side.
client-side encryption is usually feasible if you want to store or resend data encrypted or signed to other systems.
Usually adding more complexity doesn't add security.
I read there are some RSA libraries for javascript to encrypt/decrypt data
Just search for some https://gist.github.com/jo/8619441 or there is CryptoWebAPI https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
the issue is - are you sure you need RSA? How would you manage and exchange keys? How would you ensure key authenticity?
but I hear like RSA is old and slow
RSA is old and slow and yet used and secure (when implemented properly). RSA is used along other (symmetric) ciphers to ensure speed and effectiveness. It is called hybrid cryptosystem
There are two used asymetric systems, RSA and ECC. Regardless that using ssl will ensure confidentiality and integrity, in most of the cases you would need to really justify using RSA on the client side
I have an app using HTML5 caching for an "offline mode". When the app is offline, data is stored via javascript in localStorage to be sent to the server when the app comes back "online". I would like to run some of this data through an encryption before sticking it in localStorage in a way that can only be decrypted on the server.
I was thinking that a public/private key would be the way to do this. Is that a reasonable way to go about things? Are there any good javascript libraries for handling this sort of thing client-side? Are there good ruby/rails libraries/gems for handling this server-side?
If you only want to encrypt data in localStorage, you can use public key cryptography. Don't generate the keys in JS, do it server side, and send the public key with the page. Unfortunately, I don't know any well tested and maintained crypto library in Javascript.
For the level of security you're aiming at (just a little layer to prevent the user from reading the data), you can choose whatever implementation you want.
On server side, you can use the OpenSSL gem with the class OpenSSL::PKey::RSA.
For anyone else reading this: Don't use Javascript crypto, it's bad!
For handling this client side, there is the handleStorage plugin for jQuery, which is really easy to use, but is GPL. If you cannot use that due to licensing issues, you can combine the jStorage jQuery plugin with the blowfish jQuery plugin.
I am searching for a way to clientside decode RSA respectively openssl encoded messages.
Idea:
Special data is only stored encrypted with a public key on the server so that nobody is able to see the real data - even in case of server hacks.
An admin in the adminforce then can "open" these files by transfering them to the browser and some javascript code will decode the data so that it'll never decrypted on the server, only on the secure clientside.
I really need it to be decoded direclty in the browser with custom javascript because these data has then to be used by some algorithms clientside in js.
Problem:
There seems to be no openssl library in javascript or i didn't find one yet. While there are several pure js implementation of RSA they only implement the plain RSA algorithm but, plain RSA is not secure to be used as a block cipher and has some attacks like "choosen plaintext attacks".
Does anybody know of an javascript implementation of openssl decoding, or a plugin for firefox/chrome which adds these features to the document? Or any other secure asymetric encryption that's built into javascript?
As I was pointing out in a comment to your question, the vector of attack you're envisaging (compromised server) implies that the JavaScript is likely to be compromised too, in which case the JavaScript code running on the client shouldn't be trusted anyway. (It would be quite easy to make the JavaScript send the deciphered data back to the server with an asynchronous request in the background: again, since the server would be under the attacker's control, there wouldn't be any need for tricks to circumvent same-origin policies there.)
I would suggest going down the route of a standalone application (such as Java WebStart), perhaps signed (with a private key that's not held on the server).
If you're still willing to go ahead with this sort of architecture, avoid releasing the user's private key into the JavaScript at all cost. This could compromise the user's private key, not just the encrypted data.
When you use a private key in your browser for SSL/TLS client-certificate authentication, the private key isn't exposed to any code used by the server. It's used by the browser for the handshake, and the server gets the certificate (which is public), but the private key doesn't go anywhere near what the HTML+JS code can see. (In fact, in OSX with Safari, the private key is used by the underlying SSL/TLS library, and not even exposed to the user process.)
The JavaScript libraries for RSA that I've seen require direct use of the private key, that is, they need to be able to use the private exponent directly. That's clearly not good if you're in a situation you can't trust the server.
Being able to use a private key within the browser for RSA operations, without letting the script get hold of the private material itself would require tighter integration with the browser, in particular, some API to sign and decipher that would use these functions directly in the browser's security mechanism, without exposing the private key material (overall, a similar approach to what PKCS#11 offers to applications using it).
As far as I'm aware, the current Mozilla crypto JavaScript API doesn't provide functions to decipher/sign using the browsers (it's only for certificate request and key generation). There seems to be plans to do this, though:
https://wiki.mozilla.org/Privacy/Features/DOMCryptAPISpec/Latest
http://mozilla.ddahl.com/domcrypt/demos/demo.html
On the IE plaform, CAPICOM should have been of interest, but it seems to be deprecated nowadays.
Encrpytion is complex and expensive - particularly assymetric encrpytion (in most cases the assymetric encryption is only used to encrypt a randomly generated symmetric algorithm key).
There are implementations of RSA (and probably other asymmetric algorithms in javascript) and in some cases, compatible implementations in other languages (usually C) - try google for specifics - but I'm not aware of any which handles x509 encryption. OTOH writing a java applet to do this would be trivial.
But why bother? From my understanding of what you've written, you'd get just as much functionality for a lot less effort by using a symmetric algorithm and never sending the key back to the server:
allow the user to enter some data in a web page
allow the user to enter an encryption key
encrypt the data using the key
send the encrypted data back to the server
provide a decryption page where the user can retrieve the encrypted content and enter the key
decrypt the contents
Instead of relying on web server to send you both the encrypted data & the associated JavaScript code to decrypt the data (which could be corrupted in case of a compromised server), you could only download the data from the web server & decrypt it with a standalone application or a webpage with JavaScript that does NOT come from the same webserver (could be from another server or a local file). This way there wouldn't be any responses returned to the originating server or the attacker.
The data kept on the server could be encrypted with a key that only you know about and can decrypt (AES or RSA), and server could only be for storage. For decryption, download data to a trusted local machine first, so you only you will have access to unencrypted data, of course for a very limited amount of time.
Check out this native implementation of TLS in JavaScript.
Here's a guide to enable Windows Subsystem for Linux in Win 10 to install
Bash, which comes with SSL. Check your version & get the latest.
think about this. if there is a server hack, the hacker will have access to your encrypted data and to all your site source code. including the one used to decrypt the data. and it can get those from the website interface in plain javascript by looking at the source of the page.