Xcode: Storing API Secrets & IDs Securely - objective-c

I am developing an app and need a way to securely store API secrets and IDs. I understand that storing these strings directly within source-code is insecure as the code can be decompiled by hackers. I was wondering what the best way of hiding and securing these strings is and whether there is standard practise for doing such? I know this
From my own research I understand that hashing only allows a one-way encryption for verification of a string and that encryption allows two way encryption/decryption via the use of an encryption key. Therefore it may be necessary to hide the encrypted keys and their string's within a file.
Thanks
D

The place to save keys and API secrets is the App Keychain.
The keychain is designed to store secrets in a secure encrypted manner, there is no better way in iOS.
See iOS Keychain Services Tasks.
There are many source on SO of how to access the keychain.

Related

Hashed Passwords in ActiveMQ Classic?

We are currently using ActiveMQ 5 with the SimpleAuthenticationPlugin and encrypted passwords in property files. In the future, we want to use password hashes instead of encrypted passwords in our property files. Is there an easy, out-of-the-box way to do this? Preferably one that does not involve writing custom plugins, using 3rd party components or switching to another broker, e.g. ActiveMQ Artemis?
In short, no. There is no easy, out-of-the-box way to use password hashes instead of encrypted passwords in your property files.
The underlying use-cases for encrypting passwords vs. hashing are different. Encrypting passwords holds open the possibility that they may be decrypted. This is useful for situations where a middle-man (e.g. the broker) needs to use the password to access an external system (e.g. a database). Hashing passwords eliminates the possibility of decryption and is only useful for comparisons (e.g. comparing the hash of an incoming passwords against an existing hash).
The password security functionality in ActiveMQ 5.x makes no distinction between these use-cases. Everything is encrypted and decrypted the same way and passed through to the underlying components (e.g. the security plugin).
Furthermore, the SimpleAuthenticationBroker makes a simple comparison (as the name suggests) between the incoming password and the password recorded in the configuration without any consideration that the recorded password is hashed.
To get around this limitation you'd need to implement your own security plugin and hashing functions (since the built-in encrypt command won't suffice).

Where to store credentials for devops?

We have code (in git) together with configuration/deployment/build scripts (fabfile.py, circle.yml, Dockerfile etc) which result in a pretty seamless automatic build/deploy process. The one part which is not seamless is where to store credentials of various kinds. These are things like ssh keys, code signing certificates, aws access keys, ssl certificates... Currently the process is to copy the needed keys/certs from a flash drive and then (eg) run fabric.
It seems like storing credentials like this in git (alongside code) is not the best place, but what is the best place? Is there a recommended best practice for where to store information like this for devops? Is there a reference that discusses different options with their pros and cons?
The problem of secrets management is still something that hasn't exactly been "solved" by the use of any tool.
You can use any of the various Secrets Management Tools (each offers different types of benefits / integrations).
I personally prefer Hashicorp Vault. Cyberark is another good one.
The way you use these tools in your solution however, there are some common use patterns.
1) You can store your secrets in code in your SCM IF they are encrypted... But this still results in the same problem, you still need to deliver a secret securely at deploy time (or have it available at startup) to be able to decrypt the secrets (password, credentials, secrets, certs) that have been deployed. That is where the Secrets Management Tool (such a Vault) comes in. The tool will allow you to securely retrieve your secret for use in decryption of the secrets when it's needed.
2) The other way as mentioned above is. Is to actually store all secrets, certs etc. outside of the SCM in the Secret Management Tool itself and retrieve them at deploy / startup time.
Obviously there are pros and cons to doing things either way. i.e. the first approach reduces complexity as you only manage one or two secrets at any given time. On the other hand, if you store all secrets in a vault, the potential for compromises associated with your entire ecosystem is reduced, as access to a single secret doesn't allow someone access to every other secret.
At the end of the day it all comes down to your use case / the security constructs available and of course the people you are surrounded with. Because at the end of the day, someone, somewhere needs to know a secret...
Yes. There is a recommendation. It is the usage of Cloud Vault. Take a look on some good examples:
https://www.hashicorp.com/blog/vault.html
https://blog.keepersecurity.com/2016/08/16/keeper-for-devops-more-than-just-passwords/
It's a kind of best practice to use a proper Security when it comes to credentials. As it can lead to Web Hack and other potential loss to the company.
Best way to do it to use Kind of Vault.
https://www.vaultproject.io/
https://docs.ansible.com/ansible/2.4/vault.html
AWS KMS

Cryptographic Agility and Key Management

I have a design question. I have a web application that uses .NET encryption APIs to encrypt/decrypt data. (App uses old crypto algorithms like MD5 and SHA-1). Also, app hard-codes the encryption keys in the production code.
I would like to;
1 ) Update existing old algorithms (MD5 and SHA-1) to new ones.
2 ) Move encryption keys from source code to a secure share.
3 ) Can change the encryption keys easily and regularly
My Design;
Algorithm Update
For the algorithm update, we use specific .NET implementations of crypto algorithms. We use classes like MD5CryptoProvider or RijndaelManaged. These are all hard-coded. I am going to remove the specific algorithm dependency and make it more agile like;
HashAlgorithm algo = HashAlgorithm.Create(MyPreferredHash.ToString());
algo.ComputeHash(...);
MyPreferredHash value will be loaded from a config file so that we can change this when we want to.
Question: Upgrading the code is easy to do this. However do you see any potential issues with changing crypto algorithms? We do not store any encrypted or hash data anywhere and web application is stateless. All the hash values are generated and appended to url strings and decrypted from another pages. Therefore, no data is stored. Except the cookies. When we encrypt cookie and send it back to user, we decrypt it when server receives it. In this case, i thought of destroying the cookie and send a new one to the client. Is this reasonable? Any other issues you think of ?
Key Management
Second part of the design, is to remove hard-coded keys from source code to secure share. After this, I need to be able to rollout new encryption keys. Each encryption key will be associated with a expire date. When we rollout a new encryption key, new key will be used for encryption and decryption. If it fails to decrypt, then we can try old keys. Old keys will be used for decryption or verification until their expire date. When they pass their expire date, they should retire.
For the storage; I am thinking of storing the encryption keys in a config file in the local machine as "encrypted" by a master key which will reside in a secure share. Therefore, anybody who doesn't have access to this secure share will not be able to see the master key. Master key will be loaded from secure share to machine registry when a machine reboots. The encryption keys in the local machine will be loaded from config file (local) and decrypted by master key in registry.
This storage choice will give us storing only one master key in a secure share and also historical changes to the encryption keys as we will store them in version control system.
The challenging part is the key change/update.
What is the recommended key change algorithm here for a distributed web application? If we are doing partial deployment after a release, not all the machines will have the same config file content (e.g. new encryption key added). All site deployment can take 1-2 weeks. This is also another concern that if we should wait for all deployments complete so that these keys will be active after that.
Any other feedback?
You are quite right to design your app to be agile in the face of unknown future attacks on particular encryption algorithms.
The simplest way to future-proof your app in a robust way would seem to be to switch to using a standard data format for your encrypted information, and use a standard library to do the hard lifting. The choice of a specific standard to use would depend on what kind of data formats you're working with, but there are good candidates to choose from. Then when there is a future attack, you can just change some parameters, or update to the latest version of the implementation.
Doing crypto is very tricky. Best to leave it up to the experts.

Correct and secure manner of storing in-app-purchases

What is the best way to store an in-app-purchase on a device,
so that the purchases can also be accessed offline but
the security of the purchases are not compromised?
Do not store anything valuable on the device as it cannot be trusted and it can easily be compromised by someone motivated.
Now, all of this depends on the type and value of the item that is being purchased and what happens if its compromised.
If its truly valuable then use a remote secure server for managing secure items. In app purchases include a receipt that can be verified by your remote secure server talking to apple's servers directly through a secure connection. See this link to verifying store receipts.
As far as I know, the most convenient way to securely store a purchased asset would be to use some form of encryption.
The user should be able to download an encrypted asset, and the app should decrypt it on the fly.
However, make sure that you store the key in a secure fashion as well, as string keys (within the app binary) can easily be recovered by a skilled hacker. A good way to secure the key would be to use some sort of authentication with a server-based system. The app would get the key off the server and keep it only for the few moments required to decrypt the asset.
This defense mechanism is not impregnable; I feel that it is sophicaticated enough to discourage most users from attempting to undermine it.
To decrypt your assets on the device, a good idea would be to use CommonCrypto. It's provided by Apple (with the iOS SDK), so you don't have to build it from scratch and you don't have to provide documentation (required by US law) for your app. I find Jim Dovey's Common Crypto wrapper the easiest way to use it.
Hope that helps. :)
You'll want to encrypt the file, for which your best bet is probably Common Crypto. In order to be able to access the data offline, you need to store the encryption key on the device.
The solution is to use the keychain: Use SecRandomCopyBytes to generate a key of sufficient length, and store it in the keychain using SecItemAdd. Then use that key to encrypt the data and write it to the device's local storage in the normal manner. When it comes time to read the file back from disk, use SecItemCopyMatching to load the key from the keychain and use it to decrypt the data.

Hashing Credentials in Objective C

I am trying to store a username and password to hash against for future offline logging in. What is the best way to do this in objective c?
I will need the password to be stored securely.
Well, you can either create a file and store the information there, or you can put it in NSUserDefaults. I guess it depends somewhat on what your program does and how you really want it to work. If you're trying to store sensitive information (like plaintext passwords), you can use Keychain Services.
Use Keychain services (or keychain services for iPhone)