How i can store my password in Titanium? - android

How i can store my password (string) in titanium application?
Is titanium have analog for android secret key, for example?
(i need it only for android)
Thanks!

iOS (and Mac) has a mechanism for storing passwords and things like that securely called the Keychain. With Titanium, there is a module that supports this API called securely.
Once you have securely installed, it is a simple matter to save the password at this point:
var securely = require('bencoding.securely');
//You can provide optional identifier, if none provided securely uses your bundle id
// This wraps the Keychain functions
var SecureProperties = securely.createProperties({
identifier:"Foo",
accessGroup:"Bar"
});
// Now add it to the properties
SecureProperties.setString('Password', the_password_var);
// Get it back
var MyPassword = SecureProperties.getString("password");

Have you checked the FileSystem of Titanium. You can use Properties to store data
Have you tried using this
Titanium.App.Properties.setString("password","P#ssw0rD");
var MyPassword = Titanium.App.Properties.getString("password");
Please check this also

Related

How to Amazon S3 pre-signed URL from android app without exposing Amazon Web Services credentials

In my android app, I used Amazon S3 pre-signed URLs to display images in the app using the below code
var preSignedUrl = ""
val s3Client: AmazonS3Client?
val credentials: BasicAWSCredentials?
credentials = BasicAWSCredentials(BuildConfig.AWS_ACCESS_KEY_ID, BuildConfig.AWS_SECRET_ACCESS_KEY)
s3Client = AmazonS3Client(credentials)
try {
val s3URI = AmazonS3URI(imgUrl)
// Set the pre signed URL to expire after one day.
val expiration = Date()
var expTimeMillis: Long = Instant.now().toEpochMilli()
expTimeMillis += (1000 * 60 * 60 * 24 * 7).toLong()
expiration.time = expTimeMillis
val generateSignedUrlRequest = GeneratePresignedUrlRequest(s3URI.bucket, s3URI.key)
.withMethod(HttpMethod.GET)
.withExpiration(expiration)
val url: URL = s3Client.generatePresignedUrl(generateSignedUrlRequest)
preSignedUrl = url.toString()
Logger().logInfo("AWS", "getImagePreSignedUrl $preSignedUrl")
}catch (illEx: IllegalArgumentException){
Logger().logInfo("AWS", "getImagePreSignedUrl err ${illEx.message.toString()}")
}
return preSignedUrl
But after releasing the app to google play it gives me the below warning
Your app(s) expose Amazon Web Services credentials.
Please advise me on how to achieve this in the app with or without storing AWS key and secret in the app?
A native Android app cannot use most of the ways that other apps can use to read creds. For example, a Native Android app cannot load credentials from the [default] credentials profile in the shared credentials and config files ( that can easily be done using an app like a Java Desktop Swing app).
Using a StaticCredentialsProvider is a reasonable way to solve it. This does mean that you have to specify your creds in the code when using this provider.
I have a crude idea.
You will need, API Gateway, AWS Lambda and SSM Parameter Store/Secrets Manager.
Create an API Gateway. Secure incoming requests by providing API Keys for your Android App.
Trigger a Lambda function to retrieve Credential stored in Secrets Manager or Parameter Store.
Encrypt the data using a private key available to your application.
Send the encrypted Secret and Access Key in the response.
Decrypt the data on your application.
This is technically a burden and you should do it once when your application initiates and then store the credentials in Shared Preferences and stop the retrieval until you have some values in preferences.
Or it is up to you how you want to manage it.

Is it possible to secure the Android KeyChain with an HSM?

For security reasons I want to store my private key in the HSM and then share the private key with another app via the KeyChain. The KeyStore mentions that it can be backed by the HSM but I haven't found any documentation that states it's possible with the KeyChain.
Based on the KeyChain documentation, the KeyChain is the proper way to share between apps:
Use the KeyChain API when you want system-wide credentials. When an
app requests the use of any credential through the KeyChain API, users
get to choose, through a system-provided UI, which of the installed
credentials an app can access. This allows several apps to use the
same set of credentials with user consent.
So, is it possible to secure the Android KeyChain with an HSM?
After a lot of searching, I finally found that the answer is yes, it is possible.
The Android 4.3 changelog seems to be the only place that documents it:
Android also now supports hardware-backed storage for your KeyChain
credentials, providing more security by making the keys unavailable
for extraction. That is, once keys are in a hardware-backed key store
(Secure Element, TPM, or TrustZone), they can be used for
cryptographic operations but the private key material cannot be
exported. Even the OS kernel cannot access this key material.
I tested this with code and it seems that once you import a KeyPair into the KeyChain it is automatically put into secure hardware. This is the Kotlin code that I ran to test:
GlobalScope.launch {
context?.let { it1 ->
val privKey = KeyChain.getPrivateKey(it1, "device_certificate")
Log.d("App", privKey.toString()) // Shows that this is an AndroidKeyStoreRSAPrivateKey
val keyFactory: KeyFactory = KeyFactory.getInstance(privKey?.algorithm, "AndroidKeyStore")
val keyInfo: KeyInfo = keyFactory.getKeySpec(privKey, KeyInfo::class.java)
if (keyInfo.isInsideSecureHardware()) {
Log.d("App", "The key is in secure hardware!")
}
else {
Log.d("App", "The key is not in secure hardware!")
}
}
}
which printed "The key is in secure hardware!".

Equivalent to storing cookie on Mobile application without browser

I'd like to know the mechanism for storing a secret key on a mobile application for session authentication. I have a Tornado webserver that will use third party external services to authenticate users with E.g. Facebook or Google. I'm familiar with storing cookies using the set_secure_cookie when using a browser. However what if a mobile application is now connecting and doing the authentication. What mechanism would I use to store a secret like a secure cookie for future session authentication? The below shows the code for validating a user:
class GoogleOAuth2LoginHandler(tornado.web.RequestHandler,
tornado.auth.GoogleOAuth2Mixin):
async def get(self):
if self.get_argument('code', False):
user = await self.get_authenticated_user(
redirect_uri='http://your.site.com/auth/google',
code=self.get_argument('code'))
# Save the user with e.g. set_secure_cookie
else:
await self.authorize_redirect(
redirect_uri='http://your.site.com/auth/google',
client_id=self.settings['google_oauth']['key'],
scope=['profile', 'email'],
response_type='code',
extra_params={'approval_prompt': 'auto'})
How would this be modified for a mobile application that doesn't rely on a browser and cookie support?
In iOS, there is an API in the NSHTTPCookie class where you can save the entire http response string.
The code will be something like below to create a cookie.
if let requestUrl = url {
let httpCookies = HTTPCookie.cookies(withResponseHeaderFields: response.allHeaderFields as! [String : String], for: requestUrl)
}
Then you can save the cookie,
HTTPCookieStorage.shared.setCookies(httpCookie, for: url, mainDocumentURL: url)
You can also access this cookie and set it to the WebView if needed.
I don't know whether it is what you are looking for but you could you use the SharedPreferences system, it is very simple and allows to save locally key-pair values to store any useful information.
With Android you can use the SharedPreferences or the EncryptedSharedPreferences to add an extra security layer…
And with iOS you have roughly the same mechanism called NSUserDefaults that allows as well to store key-pair values, allowing also extra security layers.

How Do I manage Android Keystore KMS for symmetric encryption and decryption?

I want to encrypt and decrypt with symmetrically with android Keystore KMS. I'm aware with Google cloud KMS, and AWS KMS, but I don't want to handle with that platform.
How to manage this generated Android Keystore private key for both (client, server) sides?
I have created a private key for encrypting and decrypting, but hard to manage for the store and share this key.
I had stored that private key in Private SharedPreferences for reuse but There is one problem is that, this private SharedPreferences is not secured because all can observe this private SharedPreferences file in the rooted device.
Refer this link to get information about generating a private key for Android Keystore.
I'm new with tink, so please help me to out this. if there is a wrong thing in my idea then feel free to give your opinion.
Android Keystore is a client side KMS, you cannot use it on server side.
If you want to use Tink with Android Keystore on Android, please take a look at AndroidKeysetManager. Here's an example:
String masterKeyUri = "android-keystore://my_master_key_id";
AndroidKeysetManager manager = AndroidKeysetManager.Builder()
.withSharedPref(getApplicationContext(), "my_keyset_name", "my_pref_file_name")
.withKeyTemplate(SignatureKeyTemplates.ECDSA_P256)
.withMasterKeyUri(masterKeyUri)
.build();
PublicKeySign signer = PublicKeySignFactory.getPrimitive(manager.getKeysetHandle());
This will read a keyset stored in the my_keyset_name preference of the my_pref_file_name preferences file. If the preference file name is null, it uses the default preferences file.
If the keyset is not found or invalid, and a valid KeyTemplate is set with AndroidKeysetManager.Builder.withKeyTemplate(com.google.crypto.tink.proto.KeyTemplate), a fresh keyset is generated and is written to the my_keyset_name preference of the my_pref_file_name shared preferences file.
On Android M or newer and if a master key URI is set with AndroidKeysetManager.Builder.withMasterKeyUri(java.lang.String), the keyset is encrypted with a master key generated and stored in Android Keystore. When Tink cannot decrypt the keyset it would assume that it is not encrypted.
The master key URI must start with android-keystore://. If the master key doesn't exist, a fresh one is generated. Usage of Android Keystore can be disabled with AndroidKeysetManager.Builder.doNotUseKeystore().
On Android L or older, or when the master key URI is not set, the keyset will be stored in cleartext in private preferences which, thanks to the security of the Android framework, no other apps can read or write.

Where to keep the OAuth client credentials on Android

I have an Android application that interacts with a WebAPI through OAuth security. For getting the access token, I need to send the OAuth credentials (i.e. client id and client secret) in the header of the request. My question is, where should I keep these 2 values (client id and client secret) for the application to use it when required. Currently, I have just hardcoded it in the call. Is it safe to keep these in the strings.xml file?
Hidden in BuildConfigs
First, create a file apikey.properties in your root directory with the values for different secret keys:
CONSUMER_KEY=XXXXXXXXXXX
CONSUMER_SECRET=XXXXXXX
To avoid these keys showing up in your repository, make sure to exclude the file from being checked in by adding to your .gitignore file:
apikey.properties
Next, add this section to read from this file in your app/build.gradle file. You'll also create compile-time options that will be generated from this file by using the buildConfigField definition:
def apikeyPropertiesFile = rootProject.file("apikey.properties")
def apikeyProperties = new Properties()
apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))
android {
defaultConfig {
// should correspond to key/value pairs inside the file
buildConfigField("String", "CONSUMER_KEY", apikeyProperties['CONSUMER_KEY'])
buildConfigField("String", "CONSUMER_SECRET", apikeyProperties['CONSUMER_SECRET'])
}
}
You can now access these two fields anywhere within your source code with the BuildConfig object provided by Gradle:
// inside of any of your application's code
String consumerKey = BuildConfig.CONSUMER_KEY;
String consumerSecret = BuildConfig.CONSUMER_SECRET;
It seems you should be using a different OAuth Flow. As you experinced, Native Apps can't keep secrets. You can read about recommendations for OAuth and native apps here. https://www.rfc-editor.org/rfc/rfc8252
Your probably want to look at Authorization Code Flow with PKCE. Here you accept the fact that a native apps can't keep a secret. You can find a relatively simple explanation of the flow here: https://auth0.com/docs/flows/concepts/auth-code-pkce
As an alternative you can look at dyanmic client registration (https://www.rfc-editor.org/rfc/rfc7591) but it might be overkill for your application. Using dynamic client registration you won't have to hard code the client secret
If you are concerned about security then you can save the data in SharedPreference by encrypting and saving encryption keys in Android Keystore.
The Keystore is not used directly for storing application secrets such as password, however, it provides a secure container, which can be used by apps to store their private keys, in a way that’s pretty difficult for malicious (unauthorised) users and apps to retrieve.
Here is nice tutorial for creating keystores.
http://www.androidauthority.com/use-android-keystore-store-passwords-sensitive-information-623779/
No, it's not safe to keep it in strings.xml. Use SharedPreferences instead. For example:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
and then store your client ID and client secret like this:
sharedPreferences.edit()
.putString("client_id", "your_client_id")
.putString("client_secret", "your_client_secret")
.apply();
To get the client ID and client secret back from SharedPreferences:
String clientId = preferences.getString("client_id", "No ID");
String clientSecret = preferences.getString("client_secret", "No Secret");
Please use SharedPreferences to store secure data, because if any one reverse engineer your application, they will get hard coded strings. SharedPreferences is a secure place where you can store data.

Categories

Resources