Recusing myself from my own secure system [closed] - php

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
This is more of a software engineering question than a programming one. I tried to make the title as relevant as possible, if someone feels they can word it more appropriately please let me know.
So, I have been developing an instant chat web service using asynch. javascript and PHP. The main selling point behind the application is utmost secrecy. There are many instant chat apps out there, from Live Messenger, Yahoo Messenger, IRC and Skype, to name a few. However - call me paranoid - but I felt like I could never trust the companies behind the software as very little control is exposed to the user and most seem to neglect privacy issues altogether. I'm aware there are many other secure/private IM apps, but decided to create my own, it uses SSL to encrypt communication between all points of use (user->database->user), the to/from properties within the message table are SHA256 hashed with a salt and as a further precaution messages are automatically deleted from the database as soon as the recipient receives (or requests I should say) the message.
At the moment the messages themselves are left plain text. I could use PHP's various encryption libraries but how would I do so in a way that would remove the potential for myself, the owner, to decrypt messages thus compromising privacy?
I would by no means do this of course, I would just like to prove privacy to this extent. If I were to encrypt with a password, I would know the password. If I were to encrypt with a programmatic password, I would know where PHP would store the password.
Is there a way to solve this? Or does this just end with trust?
UPDATE: As far as I'm aware PHP is stateless, but sessions for example force the server to store data in memory, could this be a solution to have the key/password stored in the memory?
Thanks for any ideas or advice.

The typical way this type of problem is solved is with public key encryption. You can read here for an overview: http://en.wikipedia.org/wiki/Public-key_cryptography.
In a nutshell, every user is issued a public key/private key combination. The public key is public so you can get anyone's public key. The private key is kept only by the user that it belongs to. The key to public key cryptography is the math that allows one to encrypt something using the public key, but only decrypt it with the private key. So you can obtain someone's public key, encrypt a message destined for them and they are the only ones that can decrypt it with their private key.
In your scheme, public keys can be kept on your server and requested by the client. Public keys are available to anyone. In a browser-only environment, it's a challenge to store a private key. It could be stored in local storage, but then it can only be used from that particular computer. If you allow it to be stored on your server so the user can retrieve their private key no matter where they are, then you're back to the same problem you originally have (you have to trust the server and the server author that they aren't accessing the private key themselves).
There's a more complicated algorithm that tries to cache the public key/private key (probably in local storage), but anytime it is not available any more (like when the user switches computers), you simply coin a new one and store that locally and update the directory with the new public key. This has the advantage that you can continue to use the system from a new computer, but the disadvantage that you won't be able to read messages encrypted with a prior public key unless you somehow have the private key that corresponds with that public key. So, this could work in a live instant messaging scenario where messages are never saved on the server for you, but not work if the server holds messages for you and you are expected to be able to read them from any location, each with their own key pair.
SSL solves this issue by using dynamically generated public key / private key pairs but they are negotiated and exchanged in a direct end-to-end connection (so there is no node in the middle that gets to see or store unencrypted data) so another possibility would be to use peer-to-peer gaming technology (which has it's own warts and may not be possible in only a browser) to create a peer-to-peer connection and use SSL over that connection to either exchange security credentials (outside the view of you and your server) or to just directly exchange the messages. Your server would be used to facilitate two endpoints connection and communicating that desire, but not used for the exchange of security information.

You could do the encryption on the client. If you want utmost privacy, then you don't trust ANYTHING on the server. If the message and/or decryption keys never hit the server, then you essentially can't read the message even if you're tempted to do so.
Of course, now you've got a new problem - how to exchange decryption keys between two or more of your clients without involving your server.

Related

SAML private key leak

I have encountered a data leak recently and it turns out source code got leaked.
I'm analysing everything that might come back to bite me and of the things is SAML private key.
Could a private key be used with malicious intent? I understand it gives the ability to decrypt SAML requests and the possibility to create some aswell, but I am far from knowledgable on the subject.
Thanks!
Z
First just as a note. Never store any secrets in source code. There are many good solutions available for secrets management.
Next, as with any leakage of keys. Change the key immediately so that it can not be used by anyone anymore.
One idea could be to try and monitor any usage of the old key to get a understanding of if anyone is trying to use it. If you have any good logs at the other party on the SAML communication you could try to see if there have been request from other IPs than yours.
As for risks. Take this as advice, real risk will depend on context.
If you are the SP the private key is user to authenticate and sign when sending messages to the IdP and decrypting message from the IdP. Signing and auth probably includes AuthnRequest, possibly Single Logout messages and Artifact binding artifact exchange.
In a AuthnRequest there is generally not much that is sensitive to modification.
Creation or modification of SLO message could lead to signing out users with they requesting it. Not good but not the worst
Compromizing the exchange in the artifact binding could let the attacker get a hold of the Artifact, but this is generally no worst than most cases where another binding is used.
As for decryption. It depends on the sensitivity of what your encrypting. The basic information inside a Assertion of response should not be sensetive by default, but you can include attributes by your own that can be sensitive, for example personal information. If a attacker gets a hold of a Assertion , which is sent over the user browser, they can read that information with you private key.
If you are a IdP, this one of the worst cases. If the attacker can redirect IdPs to talk to their server instead of the real IdP, they can issue SAML responses and Assertion and pretend to be any user they want into any of the connected SPs.
In this case you must really start a thorough investigation on the SPs to understand the impact.
Hope this helps. Summing up, if you are a SP there is not very much worry about. If your a IdP your in for a ride.

How to store the API keys of my clients in a secure way?

I am developing a SAAS service that allows my clients to connect third party emailing tools (eg MailChimp). I therefore ask to enter their API key associated with the desired service to allow certain actions to be performed automatically on their account.
For that I record in their database their key (s) API and the connection is done. But from a security point of view, if my database comes to be hacked despite all the predispositions taken in terms of security (prepared requests etc) ... These are all the API keys of my clients that are revealed and also email addresses of their own customers that can be retrieved, used, resold ... Because the tools I connect essentially allows to store contacts, organize and send emails.
So I wonder what is the best practice to allow my clients to use the API of their favorite tools without endangering the security of their own accounts and data of their customers (emails, etc). I am aware that currently launching my web application with this data in clear in database would be dangerous.
I thought of several solutions:
Encrypt API keys in database, but I do not see how to test them (decryption) since it's not like a password?
Store API keys on a different database hosted elsewhere, but the problem of encryption remains the same ... no?
Use an OAuth stream: it seemed to be convenient, but all the services I want to connect via API do not offer this and I'm not even sure that this is really suitable for me.
I intend to host my SAAS on Amazon web services, I saw that it was proposing a service called "KMS" Key managament storing but I do not know if it is really adapted once again to my problematic ...
If someone has already had to answer this problem, or knows how to solve it, I want to be enlightened on it!
Note: Sorry for my bad english, i'm French.
All of the solutions you mentioned are somewhat valid and a combination is most likely the best answer. Your application needs access to these API keys so it's not really possible for a hacker to gain full control of your application and not gain control to the API keys. Full control being the key part - you can make it a lot harder to get to them.
Encryption
You would need encrypt them, not hash them, with something like AES. As you need to be able to decrypt them and use them in your requests towards the 3rd parties. This will help you protect against, eg. a database leak - if someone gets your database they would have to crack the encryption to get to them (as long as the encryption is properly implemented). The encryption/decryption key would of course have to be NOT in the database otherwise the whole thing has no point :)
Separation
Different database also makes sense - if someone dumps your main database they won't get to the API keys database and would have to get deeper into the application to access this database (ideally would be a completely separate DB server only accessible from your application).
Architecture of the solution matters too - you can have one server posing as a web-interface that is internet facing and that would talk to the backend server that is not internet facing over some limited (as much as possible) API to lower the attack surface. Only the backend server would then have access to the keys database and would perform the requests to the 3rd parties. Now an attacker has to jump through several servers to get even close to the keys.
Combining the above-mentioned will ensure one would have to obtain full control of your application (and all its parts) to get to the keys, the encryption key and bypass whatever other protection you might put in place.

How can I encrypt data so that a web application can read it, but someone with access to the web server cannot? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am building a system to store survey data where one of the requirements is that if a hacker gets access to the web server, they are not able to view any of the data. But, the web application does need to be able to decrypt the data and display it (for instance an authenticated user might need to see a table containing survey responses in plain text).
I am having trouble figuring out how the web server could decrypt data without a hacker also being able to do it. Obviously if the decryption key is stored on the server access to the server also entails access to the decryption key.
The only thing I can think of so far is to distribute a decryption key to the users, have them enter it as part of the authentication process, store it in a cookie, and then submit the key with every web request so that it's never stored on the server and instead only in memory for limited periods of time. Obviously this would be served over HTTPS so that the key is also encrypted at transmission time.
I have never seen a system that requires a private key as part of the authentication process, so I'm assuming there is a much better way to do this.
While this is more of a theoretical question, the application will be written in PHP, likely using the Laravel framework, hosted on an Ubuntu server.
You're trying to solve a very hard problem, but here are some pointers if you dare go this direction:
MIT's Mylar was a recent breakthrough trying to provide a practical solution to this problem (in contrast to impractical homomorphic encryption), but it seems to have some security flaws. Nevertheless, it is the right direction to be looking for a practical solution.
There is a concept known as a zero knowledge web application, sometimes called "no knowledge", which keeps cryptographic keys on the client side and performs all encryption/decryption on the client side. Without endorsing a product, it is informative to look at SpiderOak as an example. However, be wary that if you are doing the encryption in JavaScript, then a hacker who gets access to your server can replace your JavaScript with their malicious JavaScript. How to deal with this? Look at Mylar.
EDIT:
The problem with your requirements is that a single bad (or negligent) user can break everything (i.e. expose the decrypted data to anybody and everybody). However, if that's something you are willing to live with, there are potential solutions, but they are not easy to implement.
One requirement is that cryptographic computations need to happen on client side, and the key that encrypts data needs to be shared securely between users without exposing it to the web application itself. The most realistic solution to this is having native (thick) clients and avoiding JavaScript cryptography. However, Mylar claims to solve the JavaScript crypto problem.
You will need public key cryptography to have a chance. Users will need to be able to exchange the encryption key with each other, and users need to be able to authenticate other users to prevent a MITM scenario happening from a hacked server.
Generally, I'd say you really have your work cut out for you if you want to attempt to solve this, and you will likely run into many problems. However, the main reason why I am replying is to indicate that in theory, it is not impossible, as shown by recent research in cryptography and web application security.

how to protect a site-wide secret key

Imagine a pretty standard website, with user authenticating with email/password pair. For passwords, it already ha shashing with random salt, but the rest of data is kept unencrypted.
We do another step forward and encrypt the sensitive data with a password key, the key, obviously, shall be known to the application to be able to decript the data for its operation.
we don't want to have it in the source code, so it's kept in a file and read by the app when it needs it.
we've secured the file so that only user which executes the app can read it
(this point has appeared after some discussions below) We have already considered buying hardware HSM and found that not possible (for instance we are running the server on a virtual machine)
this way we are relatively protected from complete DB stealing, right? However, the key might become known if someone gets access to the OS user with read rights.
the question is: what are the best practices for keeping such key secure?
Buy a hardware security module and keep the key in it. The key will not be able to be read.
Yubi makes a reasonably priced hsm. $500 if I recall correctly.
While we're here, your db server should be on a different box in a different network zone as your web server.

why is TLS/SSL necessary? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I know everyone uses TLS/SSL as transport layer security on the web.
What would prevent me from generating let's say keypair manually, encrypting data client-side (using JS for example) with that public key and submitting that data to my server with http's GET/POST request?
I mean - I can just use JS library to encrypt some form data with that public key - right?
Only person who has private key can decrypt it - right? And private key would be kept on the server of course. No key warning will pop up - since transmission is a regular http request. So why I need TLS?
How do you trust that the Javascript delivered to the browser is the Javascript that will encrypt with the correct key?
Think about it for a second, and realize that security best practices are very subtle and nuanced and simply slapping encryption on top is not a solution.
Also, if you're dealing with the "key popup", you've broken one leg of the TLS trust model (the trusted certificate authority) by using an unsigned server certificate.
Let's give an example of how this could go wrong. Let's say that what you're trying to encrypt is some form data and send it to the server. The server sends it's public key to the client to encrypt with. The client in JavaScript encrypts this data and sends it to the server. Assuming that's what happened you'd be okay.
Now let's explore how this could go wrong. With the status of switching and the like these days it is fairly hard to sniff someone else's packets without access to the hardware. Therefore, most of the cases you are trying to avoid also allow the attacker to present a man in the middle attack. In this case the attacker could provide the client with whatever JavaScript they pleased. A clandestine way of stealing data would be to provide JavaScript that does everything that the original JavaScript does, and the also sends the unencrypted data to another server.
This can happen in a similar fashion for data from the server being sent to the client.
P.S. If your problem is the lack of a CA signed cert, I would suggest getting a free one from http://www.startssl.com/
You are correct. You can do that, and you'll have utilized strong cryptography, which is in fact one of the underlying components of SSL/TLS.
One of the issues is that computing that for every piece of data is computationally expensive. You also need to have cross compatible libraries on the client and server that handle the encryption/decryption process.
However, you will have lost any transparency in your web application because you now have to perform this encryption process on every piece of data you need to keep secret.
TLS is session oriented, so this is not an apples to apples comparison. What TLS is doing is setting up an encrypted session that is transparent to the client and server. It's making an encrypted pipe and allowing data to flow through it. It also has baked in concepts of "Trust" and identity, so that a client can have some indication that the information they are sending is going to the person they think it is.
What you are describing is taking pieces of data, encrypting them, then sending the encrypted version, and requiring decryption on the other side prior to use. Your scheme can and will work if you want to go through the pain of getting it setup, but what have you gained? Furthermore, since your scheme will have none of the things that TLS has in preventing man in the middle attacks, it's susceptible to those problems in a number of ways -- from someone injecting their own library and key into the client so that your app starts sending data to them instead of you, or that they get between you and the client, and send data to you that your server believes is coming directly from them and is instead coming from the attacker.
Digital certificates include the public key of the subject, digitally signed by the CA using their private key. Your browser contains certificates identifying their public keys (signed, in the case of root certificates, with the same private key) and this allows your browser, assuming it trusts the pre-installed CA certificates, to verify your identity. When you access a server, the server-side certificate is used to transmit the server's public key to your browser, which it then uses to encrypt the initial exchange of credentials. When client-side certificates are required, similar considerations allow the server to identify you.
There's nothing to stop you using your public key in a JS library to encrypt data, but how is the server supposed to decrypt it? Passing it your private key negates the purpose of the private key, which is to ensure that only you can decrypt information encrypted with your public key. So the correct way to proceed would be to encrypt with your private key, but then anyone who has your pubic key can decrypt it (this technique is usually used for digital signature).
Really you should use the server's public key to encrypt your transmission, and let it use its private key to decrypt it. The whole business of secure key exchange is very subtle, and there are many examples (from IBM downwards) of companies and people developing their own encryption systems, relying on privacy of the algorithm. They have always proved to be relatively easy to break. Best not to design your own system until you have a little more security experience ...
Your question makes no sense.
If you generate a key pair and encrypt with the public key, only you can decrypt that message. So sending it to someone else is futile. You could encrypt with the server's public key, but then you have the problem of establishing exactly what that is, securely.
And then the server has no way to encrypt data back to you, unless it uses your public key, in which case it has the same problem of authenticating your identity that you already had as the client.
TLS/SSL solves those problems, and a few others you haven't thought of yet.

Categories