I read a little about Android keystore. What's interesting for me that such keystore allows using cryptographic opeations (like content signing and ciphering) without direct access to private key stored in a keystore. The doc says:
Android Keystore system protects key material from unauthorized use. Firstly, Android Keystore mitigates unauthorized use of key material outside of the Android device by preventing extraction of the key material from application processes and from the Android device as a whole
I would like to have similar solution in backend web application. The most important for me is to have forbidden direct access to private key from java process. In fact my application process doesn't need it because it only needs to sign content when sending back to the user.
I was looking in KeyStore java api but found nothing or missed something important.
Is such approach possible using standard java KeyStore?
Related
In google play game services, you have to link your apps to your Game service campaign. Whenever you link an app you have to authorize it by providing the package and then the SHA1 Signing certificate fingerprint. My question is if you generate the app's apk on a different computer, the SHA1 certificate will be different. So do you have to delete the linked app and re-add it with the new SHA1? The documentation is pretty unclear about this.
My question is if you generate the app's apk on a different computer,
the SHA1 certificate will be different
Why would the certificate be different? You must use the same keystore and provide the keystore password every time you generate the APK for a release. See the documentation about this.
Warning: Keep your keystore and private key in a safe and secure place, and ensure that you have secure backups of them. If you publish an app to Google Play and then lose the key with which you signed your app, you will not be able to publish any updates to your app, since you must always sign all versions of your app with the same key.
This question already has answers here:
How do I securely store encryption keys in java? [closed]
(4 answers)
Closed 7 years ago.
I would like to store my RSA private key, which app uses to sign its data before sending to the server, somewhere safely, so that it would be much harder to steal the key than just copy it from app folder.
I know that Java KeyStore could be used to store keys and load them by runtime, but how can I load the key from KeyStore without a password for a signed jar?
For example, I've loaded a key "mykey" into KeyStore, and I signed App.jar. I want to load the key in runtime from KeyStore automaticly, without specifying a password to KeyStore, if the app which requested it is signed.
Perhaps, I don't understand the principles of the KeyStore correctly. But the task is to sign data which is sent to server and store the key safely. (The app is a POS application, so it should be loaded automaticly, without any password given by startup).
As others have pointed out, you cannot really prevent someone who has the app (and therefore has the private key) from extracting the private key. You can obfuscate the key, which might be reasonable depending on what you're trying to accomplish. In that case, you can hide the key password in various spots in the code and use the KeyStore as you've mentioned. That's not really secure, but it might be "good enough" for your purposes.
Any key that's distributed to the end user cannot be considered secret.
More importantly, if your server is trusting any client code, signed or not, you probably have a security issue with your server. You have to find a different way to enforce your security properties than trusting the client.
I try to establish a SSL Client authentication with a PKCS#11 Card under Android. I can read the Certificate fine, but sadly i can't extract the private key, so i can't use it to create my KeyStore. Since i don't get any Lib from the vendor and can't use the SUN implementation of PKCS11, since that is not supported by android, i guess i have to override the SSLContext to change the way it handles the signing process, so i can encrypt and decrypt the Handshake via the card?
Also i can't use the full PKCS11 API i got following methods:
CK_RV C_GenerateKeyPair
CK_RV C_GenerateRandom
CK_RV C_Decrypt
CK_RV C_Sign
CK_RV C_Encrypt
The login to the Card is handled beforehand by a different Software, so i already have access.
So basically two questions:
Is there an easy way to handle the authentification without access
to the private key?
What or Where do i have to override to handle the SSL signing via the card?
Is there an easy way to handle the authentification without access to the private key?
There is no way to handle the authentication without access to the private key.
What or Where do i have to override to handle the SSL signing via the card?
Android must provide some form of PKCS#11 handler surely? If not, there is a free one by IAIK you can build yourself, I did it years ago for AIX.
I have SSL working between two Android devices running the same app using a self-signed cert and key generated using openssl and stored in keystores.
The problem is that the private keystore must be embedded in the app package somehow, and therefore becomes available to any attacker. I believe this would allow an attacker to snoop on the session and decrypt the data between the two phones.
I'm not using or requiring any of the other features of PKI, I'm just providing two keystores because the SSL connection setup requires them.
Is there a secure SSL cipher that does not need predefined PKI and generates its own keys on the fly at runtime?
I have investigated generating my own keys at runtime - creating the keys is easily done in Java but the KeyStore.setEntry() requires an an X509 certificate chain not just the public key, and Android does not contain the JCE code to generate the X509. I can do that by including the BouncyCastle (Android compatible version is called SpongyCastle) library but that adds quite an overhead to my app package size.
There is no access to a third-party trust server on the internet, the two phones could be on a private WLAN with no internet access.
As a nice-to-have bonus I'd like to be able to trust that the app is communicating with itself, not someone sniffing the protocol from a PC, but I don't think that's going to be possible as the app package contents will always be available.
To ensure you are talking to something/someone you trust, you need a mechanism of authenticating the other party. I'm not aware of a way to achieve this without a piece of data remaining secret:
Asymmetric authentication (i.e. your current implementation) requires the private key data to remain private.
Symmetric authentication requires that the shared secret remains private.
In the future, TrustZone will allow applications to store secret data in the secure element of the handset. Until that time, however, you are always at risk of malware on your devices. Adding a password to your keystore (that the user knows, not the app) might add an additional hurdle to an attacker, however once the phone is infected then the password can be snooped.
To minimise your risk profile you should produce per-device keys, rather than a single cert/key-pair combo that you incorporate into your application. This will, of course, increase the effort required to add new users as some form of registration will be required (e.g. certifying their key). Alternatively you can push the problem out to your users and have them decide who to trust, PGP-style.
How can I get the PrivateKey from a Windows-MY (MSCAPI) Certificate (marked as not exportable) to use it for the HTTPS Connection to authentificate the Client.
Thanks
I ended up having to use Java Web Start to wrap my application. It handles the SSL context stuff including prompting the user for the certificate. I attempted at first to get the private key through SunMSCAPI but the private key became corrupt every time.
Java web start was my solution. Your JAR's need to be signed to run under JWS. Your application will be launched via a JNLP file. Google JWS JNLP example for an example. It's pretty easy.