I've read so many answers and tutorials and post about push notification, I've managed the registration, creating the certificates p12 and pem files as well as apple provisioning just fine so my application knows how to receive push notifications (or at least it looks like it does)
Now I'm trying to set my server side - python/django.
I've uploaded the key & cert pem files into my server folder, following this answer here at SO. I'm getting an error when i try to ssl_sock.connect( theHost ) since the pem has a paraphrase, I've read many people saying just to remove the paraphrase but then isn't the whole security public/ private key is out of the window? and if using this approach do i need to remove the paraphrase from the pem file at apple as well? or the one i've downloaded to my mac?
To expand on meda's answer - think about this:
If you put a passphrase on certificate, you will need to hard-code the pass phrase somewhere in your django project, since it will need that passphrase to load the certificate.
If someone compromises your server, they have your certificate. "No problem!", you think. You've got a pass phrase, so they can't do anything with it!
Except they also have access to your source code.
So now they have your pass phrase, and your certificate.
So all you really did was add hassle for yourself, without any benefit.
Pass phrases on certificates make sense if the certificate is being stored among other shared assets, for whatever reason, or for high encryption concerns where the private key will ONLY be used manually, by an individual or group.
In all other cases, it's a complete waste of effort.
I used PHP to accomplish this but I can tell you about what I know:
Passphrase is just an additional encryption layer
SSL encryption alone is really secure.
If you want to remove passphrase leave it blank when you are prompt to enter one.
Related
I am using the pho MQTT client library successfully to connect to AWS. After the mqtt client is created, providing the necessary keys and certificates is done with a call to client.tls_set() This method requires file paths to root certificate, own certificate and private key file.
All is well and life is good except that I now need to provide this code to external contractors whom should not have direct access to these cert and key files. The contractors have a mix of PC and macOS systems. On macOS we have keychain I am familiar with but do not know how to approach this with python - examples/library references would be great. On the PC I have no idea which is the prevalent mechanism to solve this.
To add to this, I have no control over the contractor PCs/Macs - i.e., I have no ability to revoke an item in their keychain. How do I solve this?
Sorry for being such a noob in security aspects. No need to provide complete examples, just references to articles to read, courses to follow and keywords to search would be great - though code examples will be happily accepted also of course.
Short answer: you don't.
Longer answer:
If you want them to be able connect then you have no choice but to give them the cert/private key that identifies that device/user.
The control you have is issue each contractor with their own unique key/cert and if you believe key/cert has been miss used, revoke the cert at the CA and have the broker check the revocation list.
You can protect the private key with a password, but again you have to either include this in the code or give it to the contractor.
Even if the contractors were using a device with a hardware keystore (secure element) that you could securely store the private key in, all that would do is stop the user from extracting the key and moving it to a different machine, they would still be able to make use of the private key for what ever they want on that machine.
The best mitigation is to make sure the certificate has a short life and control renewing the certificate, this means if a certificate is leaked then it will stop working quickly even if you don't notice and explicitly revoke it.
I want to have Python send a mail automatically after certain events occur. In my script I have to enter a password. Is there any way to encrypt my password and use it in this script?
Please give an example as I am not an expert in python. I have seen few answers on this topic but those aren't discussed completely, just some hints are given.
The script needs the password in plain text to send the email. You could encrypt it, but then you also have to provide a way to decrypt it on the fly.
Let me illustrate with some pseudo code.
Right now you have something like this:
password = 'supersecret'
send_mail(password=password)
If you encrypt the password it would look something like this:
encrypted_password = 'kasdjhfkauedsjflh'
encryption_key = 'allyourbase'
send_mail(password=decrypt(encrypted_password, encryption_key)
As you can see, it doesn't really make any difference.
Encryption basically tries to rely on one (and only one) secret.
That is, one piece of data that is known to those who want to communicate but not to an attacker.
In the past attempts have been made to e.g. (also) keep the encryption algorithm/implementation secret, but if that implementation is widely used (in a popular cryptosystem) those attempts have generally fared poorly.
In general that one secret is the password. So that even if the attacker knows the encryption algorithm, he cannot decrypt the traffic if he doesn't know the password.
As others have shown, encrypting a password and giving a script the means to decrypt it is futile if the attacker can get hold of the script. It's like a safe with the combination of the lock written on the door.
On the other hand as long as you can keep your script secret, the key in it is secret as well.
So if you restrict the permissions of your script such that only the root/administrator user can read or execute it, the only way for an attacker to access it is to have cracked the root/administrator account. In which case you've probably already lost.
The biggest challenges in cases like these are operational.
Here are some examples of things that you should not do;
Make the script readable by every user.
Store the script where it can by read be a publicly accessible web-server.
Upload it to github or any other public hosting service.
Store it in an unencrypted backup.
Update: You should also consider how the script uses the password. If it sends the password over the internet in cleartext, you don't have much security anyway.
My way is to use the keyring, simply using yagmail you can have passwordless scripts by using the keyring (full disclose: I'm the developer of yagmail).
E.g. to send an email:
import yagmail
yag = yagmail.SMTP()
yag.send(contents = ["See picture below", "/local/path/to/img.png"])
To get this done, first install (below) and then register your email into the keyring once by using:
yagmail.register('myemail', 'mypass')
If you also put a .yagmail file in your home (~) folder containing your username, you can use yagmail.SMTP() in your script and safely login.
Install:
pip install yagmail # python 2
pip3 install yagmail # python 3
Ironically, I also have made gittyleaks, you can use it to discover username/passwords/email in a git repo, including all history :)
I am aware that these questions has been asked before several times separately, and most of the answers I've found are "Python is not easy to obfuscate, because that's the nature of the language. If you really need obfuscation, use another tool" and "At some point you need a tradeoff" (see How do I protect Python code and How to keep the OAuth consumer secret safe, and how to react when it's compromised?).
However, I have just made a small Python app which makes use of Twitter's API (and therefore needs OAuth). OAuth requires a Consumer Secret, which is to be kept away from users. The app needs that information, but the user should not be able to access it easily. If that information cannot be protected (and I am using obfuscation and protection as synonyms, because I do not know of any other way), what is the point of having a OAuth API for Python in the first place?
The question(s) then are:
Would it be possible to hardcode the secret in the app and then
obfuscate it in an effective manner?
If not, what would be the best way to use OAuth in Python? I have thought of "shipping" the encrypted consumer secret along with the app and using a hardcoded key to recover it, but the problem remains the same (how to protect the key); having the consumer secret in a server, and have the application retrieve it at start up (if information is sent unencrypted, it would be even easier for a malicious attacker to just use Wireshark and get the consumer secret from the network traffic than decompiling the bytecode, plus how could I make sure that I am sending that secret to my app and not to a malicious attacker? Any form of authentication I know would require having secret information in the app side, the problem remains the same); a mixture of both (have the server send the encryption key, same problems as before). The basic problem is the same: how can you have something secret if critical information cannot be hidden?
I have also seen comments saying that one should use a C/C++ extension for those critical parts, but I do not know anything about that, so if that were the answer, I'd appreciate some extra information.
If you want to deploy on servers (or laptop) you own, you can store secrets in env var or files. If you want to deploy to user, suggestion is that you, or your user should register an API key, generate ssl key, or similar.
You can code your own simple symetric crypt fucntion with a lot of data manipulation to make it harder to reverse.
It is unclear why you'd need to ship your OAuth key with the script. That would mean giving anyone access to your Twitter account, whether or not the key itself is obfuscated inside the app.
The more typical scenario is that you develop some Twitter client, and anyone who wants to run it locally will have to input their own OAuth token before being able to run it. You simply do not hardcode the token and require any user to supply the token.
I'm looking at using a crypto lib such as pycrypto for encrypting/decrypting fields in my python webapp db. But encryption algorithms require a key. If I have an unencrypted key in my source it seems silly to attempt encryption of db fields as on my server if someone has access to the db files they will also have access to my python sourcecode.
Is there a best-practice method of securing the key used? Or an alternative method of encrypting the db fields (at application not db level)?
UPDATE: the fields I am trying to secure are oauth tokens.
UPDATE: I guess there is no common way to avoid this. I think I'll need to encrypt the fields anyway as it's likely the db files will get backed up and moved around so at least I'll reduce the issue to a single vulnerable location - viewing my source code.
UPDATE: The oauth tokens need to be used for api calls while the user is offline, therefore using their password as a key is not suitable in this case.
If you are encrypting fields that you only need to verify (not recall), then simple hash with SHA or one-way encrypt with DES, or IDEA using a salt to prevent a rainbow table to actually reveal them. This is useful for passwords or other access secrets.
Python and webapps makes me think of GAE, so you may want something that is not doing an encrypt/decrypt on every DB transaction since these are already un-cheap on GAE.
Best practice for an encrypted databased is to encrypt the fields with the users own secret, but to include an asymmetric backdoor that encrypts the users secret key so you (and not anyone who has access to the DB source files, or the tables) can unencrypt the users key with your secret key, should recovery or something else necessitate.
In that case, the user (or you or trusted delegate) can retireve and unencrypt their own information only. You may want to be more stringent in validating user secrets if you are thinking you need to secure their fields by encryption.
In this regards, a passphrase (as opposed to a password) of some secret words such "in the jungle the mighty Jungle" is a good practice to encourage.
EDIT: Just saw your update. The best way to store OAuth is to give them a short lifespan, only request resources your need and re-request them over getting long tokens. It's better to design around getting authenticated, getting your access and getting out, than leaving the key under the backdoor for 10 years.
Since, if you need to recall OAuth when the user comes online, you can do as above and encrypt with a user specfic secret. You could also keygen from an encrypted counter (encrypted with the user secret) so the actual encryption key changes at each transaction, and the counter is stored in plaintext. But check specific crypto algo discussion of this mode before using. Some algorithms may not play nice with this.
Symmetric encryption is indeed useless, as you have noticed; however for certain fields, using asymmetric encryption or a trapdoor function may be usable:
if the web application does not need to read back the data, then use asymmetric encryption. This is useful e.g. for credit card data: your application would encrypt the data with the public key of the order processing system, which is on a separate machine that is not publically accessible.
if all you need is equality comparison, use a trapdoor function, such as a message digest, ideally with a salt value. This is good for passwords that should be unrecoverable on the server.
Before you can determine what crypto approach is the best, you have to think about what you are trying to protect and how much effort an attacker will be ready to put into getting the key/information from your system.
What is the attack scenario that you are trying to remedy by using crypto? A stolen database file?
I cant seem to find a reliable asymmetric encryption solution to secure data between a python based server application and a client over an open data channel.
I need some way for my client to prevent a man in the middle attack over an open data channel, my current exchange has me sending my clients a token they use to verify they are talking to my server application by checking the token is valid with a php script on my site.
This is far from ideal and could easily be compromised by waiting to be sent the token and passing it off to another user.
I have tried as3crypto's rsa encryption but it is an old implementation that is not supported by many libraries as well as having a known vulnerability.
I would really like a solution that lets me hard code public/private keys into both the client and server to prevent something like this from happening.
Since decompiling swf content is not a major problem for experienced hackers, I would strongly advise against hardcoding keys. Have you thought about using SSL at all?
Hardcoding they public keys won't help you, if someone really plans an attack, because the SWF itself is transfered over an unsafe channel, thus the keys can be exchanged just as if they were transmitted individually.
There is basically nothing you can do to prevent man in the middle attacks, you can only make them harder. I think HTTPS is about the best you can get and it's also a fairly easy solution.
After doing some research I have decided to code the part of rsa I need from scratch.
I found some python code that will generate raw integer keys of any length and looked up how the rsa algorithm works.
T^P = X (mod R) to encrypt
X^Q = T (mod R) to decrypt
Where T is the starting data, X is the ending data, P is the public half of the key, Q is the private half of the key, and R is the shared part of the key (all integers).
Data will have a nonice whenever possible to prevent replay attacks and the message as a whole will be converted to a long integer to prevent traditional bit by bit cryptanalysis.