I like to implement mechanisam where string on Cliend Browser encrypted using key before page post to server and then I can use server side C# code to decrypt that posted string using the same Key.
I am generating unique key on each page request using Random class.
ASPX File
<asp:TextBox runat="server" ID="txtData" ClientIDMode="Static"></asp:TextBox>
<asp:HiddenField runat="server" ID="ClientKey" ClientIDMode="Static"/>
<asp:Button runat="server" Text="Submit" OnClick="OnClick" OnClientClick="return EncryptData();"/>
EncryptData()
function EncryptData() {
var plaintext = $('#txtData').val();
var secret = $('#ClientKey').val();
var encrypted;// Encrypt(plaintext, secret);
$('#txtData').val(encrypted);
return true;
}
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
int key = new Random().Next();
ServerKey = key;
ClientKey.Value = key.ToString();
}
}
protected void OnClick(object sender, EventArgs e)
{
// Decrypt(txtData.Text, ServerKey.ToString()));
}
Update 1
I have seen same mechanisam on HDFC bank Login page where they first encrypt user's password and then post the form.
After some thought, here is what I propose you could do. Lets here from everyone else on what they think as well.
Create an additional key. a passphrase(probably a question and answer kind of thing, mothers name or pet name etc) and use that as the key for encrypting or decrypting.
So while logging the user will input
User Name
Password
A prerecorded question's answer which is stored on
server side already during registration
On submit.
encrypt the password with answer to the prerecorded question.
when it is received in the server side decrypt the password with answer for the prerecorded question stored in server side(a database).
If the password matches allow or otherwise deny services.
This way anyone who intercepts your request to login to the server side will not have the key to decrypt. And as mentioned by smoksnes use https for additional security
I would reconsider the usage of what you are doing. You are encrypting something with a key, and then you send that thing to the server together with the key. Sure, it will be harder to read the value and it might frighten some low-level sniffers, but it isn't secure. It's security by obscurity.
Think of it like this. Alice wants to send a loveletter to Bob, but Alice don't want anyone else than Bob to read the loveletter so she puts it in a safe. Thinking that the loveletter is safe she mails it to Bob. But she remembers that Bob cannot open the safe, so in the same package she also puts the key to the safe.
The problem here is that the post office, or any other with access to the package, can open the safe. In this analogy Alice is the client (web browser, javascript), the internet wire is the post office and the server is Bob.
There are ways to encrypt it using javascript. Such as:
http://point-at-infinity.org/jsaes/
https://code.google.com/archive/p/crypto-js/
And if you still want to encrypt the data on client side, which there's no harm in doing, I would avoid sending the key in the request back to the server. It should be enough for the server to send it to the client. Then the client shouldn't have to send it back. Instead you can store in session on server side. This way you can at least make the man-in-the-middle-threat a little smaller.
But in this scenario I would use https for sending the data instead.
The HTTPS uniform resource identifier (URI) scheme has identical
syntax to the standard HTTP scheme, aside from its scheme token.
However, HTTPS signals the browser to use an added encryption layer of
SSL/TLS to protect the traffic. SSL/TLS is especially suited for HTTP
since it can provide some protection even if only one side of the
communication is authenticated. This is the case with HTTP
transactions over the Internet, where typically only the server is
authenticated (by the client examining the server's certificate).
One may argue that https can be cracked as well, but it's still a better choice for sending sensitive data.
Related
I want to encrpyt my password and username from client side and decrypt it at server side(Asp.net core) with RSA(Or any other asymmetric algorithms). I am gonna send public key from server side so I don't need to create a public key at client side only need to encrypt it.
I am trying something like this..
var encrypt = new JSEncrypt();
encrypt.setPublicKey($('#pubkey').val());
var encrypted = encrypt.encrypt($('#input').val());
but it says JSEncrypt is not defined normally. But I don't know how to include this propery at my code.
https://github.com/travist/jsencrypt in here there is a good explanation but still I couldn't manage to do it. Also I really need a simple thing for just encryption with a known public key.
Edit 1: I am using https already but I still need to do it unfortunately.
I have a specific need for security which means I'm writing more security-related code than I'm comfortable with. If what I'm doing is solved by a library somewhere, please, let me know and I'll drop my implementation immediately.
I have a server written in Java (actually Clojure) and a client written in JavaScript (actually ClojureScript) that runs as an Electron application. I need various clients applications to exchange information through the server ever being able to access that information: I need end to end encryption.
To implement end-to-end encryption I want to have a private public key-pair generated in the client and then the public key and an encrypted version of the private key will be uploaded to the server. Then, by doing a sort of challenge response in which the client signs a piece of random data and the server verifies it, the server would authenticate the user.
The registration process includes generating an Elliptic Curve Diffie Hellman key pair, specifically, P-521 (secp521r1) which seems to be a good choice according to https://security.stackexchange.com/questions/78621/which-elliptic-curve-should-i-use
After generating that, generate a 16 byte salt and then I pbkdf2 the password 872791 times with that salt, with a keylen of 32 and using sha512. Using the hashed key I encrypt the private key with aes-256-ctr. The last step is concatenating the salt length, the salt and the encrypted private key and send it to the server.
I'm assuming all of this happens over a TLS-secured channel, HTTPS, in which the validity of the certificate of the server is verified in the usual way, through the CAs. In the future I might use certificate pinning to increase security.
Is this a sound design? Does it look secure? Is there any or all of this that I could just delegate to a third party open source library that is well maintained?
My actual code:
(def elliptic-curve-name "secp521r1") ; https://security.stackexchange.com/questions/78621/which-elliptic-curve-should-i-use
(def encryption-algorithm "aes-256-ctr") ; http://lollyrock.com/articles/nodejs-encryption/
(def hash-bytes 32)
(def salt-bytes 16)
(def pbkdf-digest "sha512")
(def iterations 872791)
(defn encrypt-text [text key]
(let [salt (.randomBytes crypto salt-bytes)
salt-string (.toString salt "base64")
hashed-password (.pbkdf2Sync crypto key salt iterations hash-bytes pbkdf-digest)
text-cipher (.createCipher crypto encryption-algorithm hashed-password)
encrypted-text (gstring/format "%04d%s%s%s"
(count salt-string)
salt-string
(.update text-cipher text "utf8" "hex")
(.final text-cipher "hex"))]
encrypted-text))
(defn decrypt-text [encrypted-text key]
(let [salt-length (js/parseInt (subs encrypted-text 0 4) 10)
salt (.from js/Buffer (subs encrypted-text 4 (+ salt-length 4)) "base64")
hashed-key (.pbkdf2Sync crypto key salt iterations hash-bytes pbkdf-digest)
encrypted-text (subs encrypted-text (+ salt-length 4))
text-decipher (.createDecipher crypto encryption-algorithm hashed-key)]
(str (.update text-decipher encrypted-text "hex" "utf8")
(.final text-decipher "utf8"))))
(defn generate-key-pair [password]
(let [diff-hell (.createECDH crypto elliptic-curve-name)
public-key (.generateKeys diff-hell "base64")
private-key (.getPrivateKey diff-hell "base64")
encrypted-private-key (encrypt-text private-key password)]
[public-key private-key encrypted-private-key]))
This is an excellent start. These kind of questions are tricky and there is no way to prove these things secure. There are some good conceptual "pillars" to guide ones thoughs on it:
The pillars of security:
Privacy:
This code does not provide it. An attacker in the middle can read the structure of the message and can understand almost all of it. This gives them a strong stance. This system is open to replay attacks.
Authentication
By matching the password hash you are giving a strong assurance that this person does indeed know the password. PBKDF2 with a salt is state of the art and looks like you have this down.
Integrity:
This code does not provide it. the public key could be changed in flight. An attacker can substitute their own public key and cause the system to generate messages that they then could read. This attack is dependent on the rest of the system to detect the breach and respond to it, by comparing the public and private keys. This could open the system to known or unknown crypto attacks by allowing a "chosen key attack" which is generally considered dangerous. You really need to assure the integrity of the entire message. An attacker can take a password and key they do know along with a private key they do know, and switch them. Combined with replay attacks this will likely break the system.
Suggestions:
The structure of the entire message must be authenticated. There are two approaches to this. Either use a keyed MAC (Message Authentication Code) or use an "Authenticated Encryption" algorithm. MACs are included in more of the common crypto libraries. Don't roll your own MAC, and don't try to use a hash for this.
The privacy of the message should be ensured. This can be accomplished by ensuring that The message is send over TLS (you may already be doing this).
the message must include protection against replay attacks. This can be done in many ways. One strong way is to use a NONCE (Number used ONCe) so the server will only ever accept each message once. This must not be "per user" because many replay attacks are cross user.
The part you are absolutly doing correctly is asking for public scrutiny early in the process. This puts you way ahead of the industry norm. remember that
"Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can't break."
https://www.schneier.com/blog/archives/2011/04/schneiers_law.html
EDIT: make sure the password that protects them from you guessing their private key is not the same password you use to authenticate them (and that there is no way for them to use the same password)
I'm developing an application where backend is asp.net owin based.
In Startup.cs I have IAppBuilder.useCookieAuthentication() { ... }. After successfully authenticated, current user with its roles can be accessed via HttpContext in all my web api controllers.
My javascript client side needs a knowledge about these roles in order to know how to display specific items. For example: user having administrator role can see additional tabs.
My question is: what's the best way to 'transfer' these roles to client side. Is it by writing some endpoint which will return these roles, or any other way?
Thanks
I totally agree with #cassandrad !
But if you want to access it as plain text, than you have to provide your own implementation of TicketDataFormat in the CookieAuthenticationOptions
public class CustomAccessTokenFormat : ISecureDataFormat<AuthenticationTicket>
{
// If you want to do custom serialization and encryption
public string Protect(AuthenticationTicket ticket)
{
return "UserName|Role1|Role2|..."; // your raw text serialization goes here
}
// Deserilaize and decrypt the ticket
public AuthenticationTicket Unprotect(string strTicket)
{
return new AuthenticationTicket(null, null); // deserialize the plain text here into an AuthenticationTicket object
}
}
You don't need to pass information about roles or permission in “raw” state to the client-side. Instead, you should have AuthenticationTicket — the thing that holds all information protected and encrypted. So, if you are using correct implementation of OWIN middleware, there is no need to do something by yourself — middleware will add all the necessary data to your response(inside cookies), client only need to resend this information back to the server next time when he wants to access some resources on the server.
And yes, I'm implying that you shouldn't have any information about permissions on your client-side — it is not secure.
This question has been asked to me in a interview. i search on web but can't find a thread that explains it in a way that makes sense to me.
Suppose is i had a web service which return a list of something and available
In public Domain(Any body can use That) For security User need A key to Access that web service.
How can i use That web service securely in Ajax.
Problem is if i use Ajax to access that web service any body can able to see my private key,
I suggest for a encryption but i have to pass that key in decrypt(as i get )in form
Than i suggest for a mediator file(at server side) on which i can call that web service but what if somebody directly access that mediator file (i know same origin policy )
i really want to know what are the possible solution to overcome to these problem and what is best practice to make a secure ajax call on rest
In fact, there is a dedicated security flow in OAuth2 for this particular use case called "Implicit Grant Flow".
You could have a look at these links for more details:
http://www.bubblecode.net/en/2013/03/10/understanding-oauth2/#Implicit_Grant
https://www.rfc-editor.org/rfc/rfc6749#section-4.2
If you don't use OAuth2, you can propose the user to authenticate and get back an access token. You could store it within the local storage of your browser but you need to be very careful with XSS. This question (and its answers) could provide you some hints regarding such issue: What are (if any) the security drawbacks of REST Basic Authentication with Javascript clients?.
Hope it helps you,
Thierry
We are using cookies for this. And like the Session we have stored the secure key on the Web-Server. With the Cookie we can get the secure key. So he just see the "key" of his key. There is no option to hide all information from the client. But you can show him information, he cant use directly.
But at all, there is the fishing problem. If someone fishes your cookies, he has your "key" of your secure key. Many others are doing it simular. E.g. Facebook.
This is not specific for Ajax calls, but since it works for both, normal GETs and AJAX Calls, it would be a solution.
If you do not have 100% control of both client side and server side, you may want to use client-side authenticate solution (e.g. Oauth 1 or 2).
If you do have 100% control of both client side and server side, easy way is to use basic authenticate + SSL.
What our project is :
- I have a restful service. We provide restful service in SSL.
- Only our partner companies can use it through internet.
What we did is:
- They have their username/password in their request (is a Ajax) in their internal application (not public-accessed web page)
- sample as following restful code (you can test by Postman):
// to inject request
#Context
private HttpServletRequest request;
#GET
#Path("/testAuth")
#Produces(MediaType.APPLICATION_JSON)
public Response testAuth() {
// TODO
// this is only a template for doing authentication in the near future
String returnString = "";
//check if authenticated
String authorization = request.getHeader("Authorization");
if (authorization == null || authorization.toUpperCase().startsWith("BASIC ") == false) {
//no authenticated
returnString = "{\"testAuth\", \"need authentication\"}";
return Response.status(401).entity(returnString).build();
} else{
String credentials = authorization.substring("Basic".length()).trim();
byte[] decoded = DatatypeConverter.parseBase64Binary(credentials);
String decodedString = new String(decoded);
String[] actualCredentials = decodedString.split(":");
String ID = actualCredentials[0];
String Password = actualCredentials[1];
String Result = userAuthenticate(ID, Password);
returnString = "{\"testAuth\", \"" +
" (" + Result + ") \"}";
return Response.status(200).entity(returnString).build();
}
}
I'm trying to create a message system with JavaScript and PHP / MySQL. I have a form with two input elements (recipient id, message content). I'm using MVC (Zend Framework 1). The form post data is send to my controller and stored in the database.
Now I want to encrypt the message before it is sent. I want to keep it user-friendly, so my idea was to use RSA (private / public key). The idea was that a private key was generated on user log in and stored in the cookies, to make sure that the private key is only on the user's machine. The public key could be stored in the user's table, so that any user, who want to send a message to him, can encrypt the data.
It is important that the key-pair is generated by the user's password. If it's random generated, it would not be possible to use multiple systems to log in, because the private key would change everytime. So that would be the mechanism to make sure, that he will always have the same private key, until he is changing his password.
I tried a few JavaScript libraries. cryptico seemed to be the right choice, because it generates private / public key by password. The problem here is, that I can not store the private key and not even look into the value.
They have an example on the website
// The passphrase used to repeatably generate this RSA key.
var PassPhrase = "The Moon is a Harsh Mistress.";
// The length of the RSA key, in bits.
var Bits = 1024;
var MattsRSAkey = cryptico.generateRSAKey(PassPhrase, Bits);
When I try to output MattsRSAkey, I only get [Object object]. It's the same when I store it in the Cookies. I tried to use JSON.stringify. With this function I can store and look inside MattsRSAKey. But when I want to use it later to decrypt the message, I get an error, that I have no valid public key. I think the private key got broken while storing it. When I read the private key from Cookies I use JSON.parse.
Is there any way to solve my problem? I just want to send encrypted messages from multiple users (public key) to one user (private key). My intention is not to have a secure transport but to store the messages encrypted in the database, so that unauthorized persons can not read it. It is important that I do not only have encryption for one-to-one messaging. This would be easy, because both users only would need to share a password for encryption.
There's a couple of things wrong here.
First, you're trying to store a Javascript object directly in a cookie. This won't work: cookies can only store string values. You will need to serialize the key to a string to store it in a cookie; unfortunately, it doesn't appear that the cryptico library exposes any methods to do this, so you will need to either implement a custom serializer, or use another cryptographic library.
Second, you are storing private cryptographic key data in cookies. This is perhaps the worst possible place to store this, as cookies are sent to the web server on every request. Local storage is much more appropriate here, as it is only accessible from Javascript code.