I don't want to use SSL to encrypt signup and signin forms for a website I'm building.
I don't have money to pay for a certificate.
I need to use encryption with jQuery and decryption with C# in my asp.net website.
Does someone have an example and how is it secure to adopt this method?
If you're not using SSL, then you're not secure, but that's not the only reason.
SSL protects the actual communication, whereas encryption protects the data you are communicating. You should not even be encrypting the passwords at all. You should be making a hardened hash of the information. A hash is a one-way function (cannot be reversed), whereas encryption is two-way function(can be reversed). Hash hardening and use includes:
Iterating over a hash built for speed, such as SHA512 a couple of thousand times or using something like BCrypt.
Use a salt - Something like a 64-bit array of jumble per user, stored in the database will do it
Encrypt the keys and salts in the DB using a key in the application layer - This means if your database is taken, they would still need the key from the application layer to access the raw hash information, as well as the salts.
You have to remember that security is built in layers. By skipping SSL, you're skipping a large portion of it. At the very least you can use makecert to create a self-signed certificate. All that will happen is that the user will be warned about it. A good SSL certificate can cost as little as $12.99 on GoDaddy. I recommend getting one as well as implementing the above.
You can do SSL without paying for a certificate, and this method get you secure only browser get information about your certificate is not qualified.
Read about this http://www.akadia.com/services/ssh_test_certificate.html
It's probably not secure at all.
SSL really is the way to go; if you can't afford a certificate, you can always make your own. Obviously those won't validate up to one of the trusted root authorities, but they are just as secure - the identity of your website will not be confirmed by a trusted third party, but the connection itself will be just as securely encrypted.
By not using SSL you're opening up your code to network sniffing attacks. Encrypting on the client side won't do any good either.
Unfortunately there's no safe way around it without getting a valid certificate. This approach would be unsecure.
I agree with the security concerns of the other individuals, if you're hell-bent-for-leather on doing it this way, you may attempt to employ a custom PKI interface. You will have to research a little more deeply on the code necessary to accomplish this but here is a link to describe the public key structure:
Public Key Cryptography
So if you manage to code up a public key RSA algorithm in jquery, you should be to match its private key decryption in C# without difficulty. This is not a recommendation because this really is only "security through obfuscation" (which is not security at all).
You can encrypt the form data with Javascript. This can be done, see http://www.movable-type.co.uk/scripts/aes.html. If data is encrypted with a key, then you'll have to store that key in javascript code and also in server-side code. Since javascript code will be client-side and key will be public, that's not secure at all :). The same is also valid for asymmetric encryption. Different data can be encrypted with the same key and sent to server.
SSL is designed to overcome security problems on the web, using public key cryptograpy and symmetric encryption tehcniques. Middle-man attack is prevented. Using SSL, you can be sure that your data is secure, not altered through the way and there is a 3rd party, certificate authority, which says that you're the person you claim to be.
If you say that I can put the key or encryption code in an applet or active-x or flash swf object and use obfuscation to secure the code, that may be a way. But again this approach is open to attacks and not secure. Obfuscation does not guarantee that your key or algorithm is safe, just hardens the cracker's job to get the key.
I hope that helps.
You could use a HMAC for authentication. This would not provide privacy but a sniffer (guy looking into then network traffic) would not be able to get the passwords nor login impersonating an authentic user. When I it does not provide privacy I mean the sniffer will see all the transferred content but not the password.
SSL is of course very secure, but an overkill for many applications.
Related
I've used ASP.NET MVC with entity framework (most recent of both) to extend an existing website's data model, but without changing user accounts and user authentication. Feel free to answer this by pointing me to other documentation or learning resources.
My question is: How does ASP.NET handle the passing of user credentials over the wire, the authentication of those credentials, and storing user account credentials? And, how would I do that myself 'manually', in terms of securing their information on front end, in transit, processing, and storage?
Security at the various stages:
Front End - No idea, but make sure forms are validated, I'm guessing? Is this the user's problem?
Transit - Use an encrypted protocol (HTTPS?), but I'm not sure how to set that up in terms of appropriate controller methods, views, and certificates.
Processing - Decrypt username/password to plaintext, hash both and find matching record in the user account table, overwrite or make sure plaintext variables aren't hanging around in code.
Storage - Only store hashes of username/password on the database.
Then once authenticated, create user-session/key that will expire at some point. Again, I'm not sure how to do this 'manually' with ASP.NET, but I know that it happens with the built-in/default login setup.
Front End
Data is not secure. Passwords are entered in an input with type "password", which will obfuscated the entered information (preventing over-the-shoulder style attacks). However, the plain-text value is exposed via JavaScript and can be read by keyloggers or other client-side malware. There's not much you can do about any of this. Ultimately, the end-user is responsible for the security of their machine.
Transit
Always, always, always use HTTPS. It's not foolproof, as was seen by the recent Heartbleed attack, but it's better than just sending everything plain-text over the wire with HTTP. Except for fundamental flaws like Heartbleed, with HTTPS, you need only worry about protecting your certificate's secret key. HTTPS is utilizes two-way encryption with secret and shared keys. The shared key is sent to the client allowing them to encrypt what it sends, but not decrypt, while the secret key allows the encrypted text sent by the client to be decrypted server-side. Hence, the need to protect your secret key.
As far as your controller actions go, if you want to enforce HTTPS only on the action, such that if the user can only access your login page, for example, at https://domain.com/login, rather than http://domain.com/login, you'd add the attribute, [RequireHTTPS]. This attribute can be added at the action level to protect just that action, at the controller level to protect all actions within that controller, or globally to force your entire application to be HTTPS only.
Processing
You do not manually decrypt the username/password. If you're using HTTPS, your application will be handed the already decrypted values by the web server. Dealing with plain-text in your application code is not problematic and is pretty much necessary. I suppose that if some malware running on your server could gain access to the IIS process in memory and decompile the machine code at runtime into to something usable where they could get at the plain-text password, etc., it would be possible to exploit this, but it's a non-trivial hack and would require your server to be severely compromised already.
Storage
Of course you only store hashes in persistent storage. These are created with one-way encryption, where you have a key and generally a randomized IV value. As long as you do not leak both the key and the IV, it is impossible to decrypt the stored value into the original string. The only vector for attack is collisions, where you essentially encrypt millions of different strings in different ways and check for a match against the target encrypted value. However, most modern encryption algorithms make this sort of attack nearly impossible, requiring even a supercomputing platform hundreds or even thousands of years to ever create a viable collision. Just stay way from MD5, which does regularly emit collisions and has entire blackhat databases devoted to matching up encrypted values to plain-text values.
I have an application which exposes service which is consumed by the web application via Jquery POST and other applications (IPad, Android, etc). I have to create an authentication system which is highly safe but still fast enough.
I thought of making a token which will be passed to the application on login and which will be used for a specific amount of time (say 30 mins) post which it should refresh itself and not expire the session. So I thought of making a token being sent to service and which will generate token. It will accept
UserId
Password (both encrypted with public key)
AppId
The server will decrypt the request by the private key and generate a token which will be valid for a specific time. Now since this would highly depend on the private key (which will be same and thus someone from within system can leak it and misuse it) so i want the private key to be refreshed after a specific time (say 2 hrs).
Question -
How do refresh Private key and ensure that the currently issues tokens will not be rejected.
Is there a better way of doing it
Is there a better way of doing it?
Yes there is, It's called SSL/HTTPS. If you are already using HTTPS then there is no need for any of this crypto-magic. If you are not using HTTPS you are already insecure by design and nothing you come up with will fix that short of re-inventing SSL.
So what should you do if the transport is secure (HTTPS)
Client makes a request for authentication sending username + password in plain-text.
Server verifies the username + password pair against the (hopefully) hashed password stored with the account.
Server responds with a token (encrypted account id, expiration, etc) using a static AES key.
Client uses the token for all authenticated requests.
Easy.
One thing you could do...
To prevent loss of credentials used on non-secure devices you should take a page from Google and others. Rather than having users entering their website passwords, make them visit and log in to your web server. From there they click a 'generate access token for device'. A unique data string (20 or more characters) is generated and recorded with their account. This 'alternate password' can then be revoked by the user from your website.
How can I make this more secure?
You really can't do much better, here is why...
Assume an attacker gains access to your private key. The attacker can then replace your server or play man-in-the-middle while stealing usernames and passwords.
To attempt to prevent this you contrive some PKI exchange to send the password encrypted by a public key the server gave you. I as a man-in-the-middle can simply give you my own public key and access the username and password and then if I choose, forward it to the real server.
--or--
To attempt to prevent this you use some salt + password hash that will be sent to the server in place of the password in clear text. I as a man-in-the-middle can simply give you a fixed value for the salt and then pre-compute a complete rainbow table for that salt value. Now I again have everyone's password (well most) in clear text.
--or--
To attempt to prevent this you use PKI to establish some secret session key and then sign and encrypt every communication. Well, gee... that sounds familiar... see SSL on Wikipedia. Realize that the ONLY thing that makes SSL secure is the protection of it's private keys. Once a private key is lost, all security and trust is lost.
Final notes:
Without being able to protect some encryption key you cannot build a secure communication.
You should also be aware that thousands of man hours have been spent on software implementations of SSL (like OpenSSL) and they constantly find vulnerabilities in their implementations. Your hope of implementing this yourself, and doing it as secure as IIS or OpenSSL, is almost NIL. That is not a Digg on you, that is just reality, I couldn't do it either I only know enough to not even try.
Lastly, my final advice is about your statement: "someone from within system can leak it and misuse it". This is your real problem. Fix that and all else will be much easier. Securing a server environment should be your first priority. Your second priority should be minimizing the impact to your customers once you fail to do the first.
Some helpful links:
How to generate password using a specific set of characters.
Another example of how to store a salted password hash.
I am currently trying to undertand how best to implement signing/verification in a .NET 4.0 C# environment.
My requirment is to be able to sign data within my system as one 'user', at some point later that data needs to be verified by a consumer.
To accomplish this I am trying to use Certificates, however this is where I begin to struggle. One aspect of my confusion is that I have been advised I can use DPAPI for certificate management, however from reading DPAPI documentation it appears to only offer a way of protecting/unprotecting arbirary data for the local host/user. Although this data may happen to be a private key, it does not specifically deal with certificates.
A first question is, doe DPAPI in any way link to the local certificate store, or other certificate management solution?
The hope was that the code would not have to locate certificates, instead simply pass the data down to a helpful API where it is either signed (on the data source) or verified (on the consumer).
Any comments are appreciated.
DPAPI is used to encrypt data that is intended to be decrypted only under the same Windows user account. It uses a symmetric encryption algorithm, so it cannot offer the signing functionality that you require.
If you wish to offer signing capabilities, then use of an signing algorithm based on a public-private key pair (with the public key distributed in a certificate) would usually be the appropriate approach. The .NET BCL does offer functionality for the signing and verification parts (including use of keys from the local certificate store), but it won't help you with the key distribution side of things.
I've been reading a little about encryption recently and am interested in protecting a licence file from tampering. Now this may not be the best way to do it, in which case I'm open to suggestions. But one way I was thinking of protecting it is to simply encrypt it.
However if I were to use encryption I'd need to use symmetric key, but this raises the question. If I store a key in the source code, with such tools as reflector, is it really worth it? It seems a fairly trivial task to obtain the initalization vector, salt, key etc and therefore break the encryption. Is there a way to protect a key in source? Or is this the completely wrong approach?
If you want to prevent tampering, you want signing/hashing, not encryption. Similar theory - but it means you can validate the file with the public key in the app, without requiring the private key that you keep on your server (and use to issue licenses).
Search for cryptographic hashing / signing.
Anything on the client side of the system can be compromised.
If you encrypt your file you must also somehow place the decryption key in your program. Anyone with a hex editor will be able to step through your code to find this key and then decrypt your license file and also create keys for your system.
Internet activation would be a good way to go, but I would see if you can find third parties to do this for you as they will have been down these roads before.
That said running your license file through some AES 256 encryption can't hurt :).
if you are speaking about MS/.NET environment, i recommend you the DPAPI.
It is an API used to store your data protected by a password. Then you can ask me "but then i have the same problem", the answer is no, because in this scenario you use a user password to protect your data. So what you have to do, to access your data, is run your application under a certain credentials. In MS environment, its the the best solution.
from the documentation:
DPAPI is focused on providing data protection for users. Since it requires a password to provide protection, the logical step is for DPAPI to use a user's logon password, which it does, in a way. DPAPI actually uses the user's logon credential. In a typical system, in which the user logs on with a password, the logon credential is simply a hash of the user's password. In a system in which the user logs on with a smart card, however, the credential would be different. To keep matters simple, we'll use the terms user password, logon password, or just password to refer to this credential.
What you're attempting is DRM; there is no 100% way to do this on current PC hardware. There are many measures you can take to obfuscate parts of your program. It's a tradeoff between how much you want to obfuscate and how many hurdles you want to make your paying customers go through.
how to encrypt soap message in silverlight.. i am currently looking for ideas... as silverlight doesn't support WCF Message Security..
i have gone through a post by Peter Bromberg but it is also not discussing the idea about when how to exchange public/private keys or sort of...
The approach discussed in the post doesn't appear to do any asymmetric key exchange (as TLS does). Instead it relies on a symmetric key that is generated based on some assembly metadata. See the last paragraph of the article:
In closing, let me just address a couple of concerns: First, nowhere here do I say that this is "better" than SSL. I provide it only as an alternative. Second, the fact that the password or other component of the generated cryptographic key may be shown in plaintext in the code is not useful to a hacker, as both the password and the hash (both of which can be generated only at runtime) are required for a valid key. The download reflects the change to using the FullName property of the assembly to generate the salt value, and the ManifestModule.Name.GetHashCode() for the password, as discussed earlier.
It's not a very strong key generation mechanism as an attacker could simply download the same Silverlight application fire up a debugger and get the key. However it will protect any man-in-the-middle attacks where the attacker only has access to your HTTP traffic.
Personally I'd stick with SSL, with a self signed certificate if the goal is to have a free solution.
How about using transport-layer security? ssl?