I use
KeyStore store = KeyStore.getInstance("JCEKS");
But is make KeyStoreException
java.security.KeyStoreException: KeyStore JCEKS implementation not found
Reason is default security provider is bouncycastle in Android.
Therefore I use
KeyStore store = KeyStore.getInstance("JCEKS", "SunJCE");
But is make NoSearchProviderException
java.security.NoSearchProviderException: SunJCE
Android does not include the SunJCE security provider and therefore JCEKS is not a supported Keystore type (neither is the older JKS format).
To create a KeyStore you can either choose the BouncyCastle Keystore
KeyStore ks = KeyStore.getInstance("BKS");
or, from Android 4.3, the new AndroidKeyStore based on OpenSSL decdicated to store app-private keys (more details here)
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
And if you have a JCEKS Keystore you will have to convert it to BKS format with keytool:
keytool -importkeystore -srcstoretype JCEKS -srckeystore my.keystore -srckeypass my_password -destprovidername BC -deststoretype BKS -destkeypass my_new_password -destkeystore my.bks
Related
With which command I can view keystore type using keytool? There is not direct parameter for it.
In list of parameters there is no parameter like -info to view information about keystore.
For this purpose you need to use parameter -list
keytool -list -keystore mykeystore.keystore
It will return list of entries and keystore info
Keystore type: jks
Keystore provider: SUN
...
I have a .pfx file that I used to generated a keystore file using the following command:
keytool -importkeystore -srckeystore TestCodeSign.pfx -srcstoretype pkcs12
Keytool came back and said 'The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format..."
So I ran the suggested command:
keytool -importkeystore -srckeystore C:\Users\USERNAME\.keystore -destkeystore C:\Users\USERNAME\.keystore -deststoretype pkcs12
I now have the backed up copy, '.old' and the new .keystore file.
In Visual Studio, I create an archive for the release version of my app. Then I click Distribute->Google Play and then hit Import to locate the .keystore file.
But when I import, I get a useless error. I checked the Xamarin.Diagnostics output, I can see another error:
[E:keytool]: ImportKey - System.AggregateException: One or more errors occurred. ---> Xamarin.AndroidTools.AndroidSdkToolException: Importing keystore C:\\Temp\\TestCodeSign.keystore to C:\\Users\\USERNAME\\AppData\\Local\\Xamarin\\Mono for Android\\Keystore\\A\\A.keystore...
And that is it. How can I import an existing pfx file into a keystore and then use that keystore to sign the application for distribution to Google Play?
I generate a .keytore file to test. When I import with the wrong password or alias, it would throw the same error. Please check your password and alias.
If you do not make sure about the alias and password, you could create a new .ketstore file to import for test.
For more details about generate a .keystore file, please refer to the MS docs.
https://learn.microsoft.com/en-us/xamarin/android/deploy-test/signing/?tabs=windows
I want to pin the ssl with bks file. but I dont know how to do that. My concern is prevent any man in the middle to see the api calls for my android app. I know that I need to pin the ssl. One way is using retrofit. (and it is too easy)
CertificatePinner certPinner = new CertificatePinner.Builder()
.add("appmattus.com",
"sha256/4hw5tz+scE+TW+mlai5YipDfFWn1dqvfLG+nU7tq1V8=")
.build();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.certificatePinner(certPinner)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://appmattus.com")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
also getting sha256 key from any web site is just tooooo easy using https://www.ssllabs.com/ssltest/analyze
And I dont understand how this way improve security. So I decided to use pining BKS file into the app. but this is too hard.
I know I should create BKS file and embed it in android app for ssl pinning. But I couldnt understand how to create that BKS file in windows 10. I have found very few info about creating BKS and they are too old to find android keytool or jre in windows. here is just one old example
http://transoceanic.blogspot.com/2011/11/android-import-ssl-certificate-and-use.html
I am stuk and I need your help. thanks in advance
Step 1: Obtain your Public Key certificate
To obtain your public key you can ask your security guy in your company or you can easily go to your endpoint (api.sample.com or sample.com, wherever you want to do SSL pinning) from your browser and click on the green lock icon > certificate.
Then drag and drop certificate icon to your desktop. Done. You have a public certificate.
Step 2: Create a BKS file
You need to download bouncy castle jar to create BKS file. The bouncy castle is a crypto API. You can download the latest release from here.
Now you can create your BKS file using keytool and bouncy castle provider.
keytool -importcert -v -trustcacerts -file "[YOUR_PUBLIC_CERTIFICATE_PATH]" -alias [YOUR_ALIAS] -keystore "[BKS_TARGET_PATH]" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "[BOUNCY_CASTLE_JAR_PATH]" -storetype BKS -storepass [YOUR_PASSWORD]
For example:-
keytool -importcert -v -trustcacerts -file "/user/mert/testcertificate.cer" -alias mytestalias -keystore "/user/mert/desktop/certificate.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "/user/mert/bcprov-jdk15on-159.jar" -storetype BKS -storepass mypassword
This command will create a BKS file with your public certificate. If
you want to add multiple certificates, run this command with your
another public certificate. This command will check the target path
and add the new certificate to the existing BKS file so that BKS file
will have both certificates inside.
Let’s add multiple certificates to the same BKS file.
keytool -importcert -v -trustcacerts -file "/user/mert/testcertificate.cer" -alias mytestalias -keystore "/user/mert/desktop/certificate.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "/user/mert/bcprov-jdk15on-159.jar" -storetype BKS -storepass mypassword
keytool -importcert -v -trustcacerts -file "/user/mert/testcertificate2.cer" -alias mytestalias2 -keystore "/user/mert/desktop/certificate.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "/user/mert/bcprov-jdk15on-159.jar" -storetype BKS -storepass mypassword
As you may see I run the same command and keytool will add another certificate into the same BKS file. But be aware that you should use the different alias name for certificates.
Let’s check if the BKS file really has 2 certificates. To list certificates in your BKS file, you need to run following command
keytool -list -keystore "/user/mert/desktop/certificate.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "/user/mert/bcprov-jdk15on-159.jar" -storetype BKS -storepass mypassword
It will show you the public certificates inside BKS file.
We have successfully created a BKS file which contains 2 different public key.
So If you have 2 different endpoints in your app and endpoints doesn’t have the same public key, you can use multiple certificates to do SSL pinning in your app.
Step 3: Apply SSL pinning to OkHttp Client
I created a helper class for ssl pinning. This class takes 3 arguments.
Context
BKS file
BKS password (which you type in the command line)
you can find the code from here
You need to locate your BKS file under your res/raw/ folder.
Almost done. All you need is attaching this SSL pinner to your okhttp client.
RawCertificatePinner pinner = new RawCertificatePinner(context, R.raw.mycertificate,
"mypassword");
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder = rawCertificatePinner.pinCertificate(builder);
return new Retrofit.Builder()
.client(builder.build())
...
.build();
I'm automating some things that involve the android keytool and jarsigner. The tool takes a keystore, the password for the keystore, the alias name, and the password for the alias / key, and I'm trying to find a way to explicitly check to see if the supplied password for the alias / key is correct.
Any ideas? Also, I need to check it without a jar file to sign - getting that file in my context is lengthy, so I want to abort sooner rather than later.
You can also check if the password is correct without attempting to change the password. I did it by listing the properties of the keystore with this command:
keytool -list -keystore <keystorefile> -storepass <passwordtocheck>
You can do it a couple of ways:
A. With keytool
If you run the command keytool -keypasswd -keystore <keystore> -alias <alias> -storepass <storepass> -keypass <keypass> -new <keypass> then you will get the error Keystore was tampered with, or password was incorrect if the keystore password is wrong, or the error Cannot recover key if the alias password is wrong. Unfortunately the return code is 1 in both cases, so you will need to do parsing of the program's output if you want to be smart about the type of error.
B. With a small Java program
Something along these lines:
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
try (FileInputStream fis = new FileInputStream(keystore)) {
ks.load(fis, ksPw.toCharArray());
}
ks.getEntry(alias, new KeyStore.PasswordProtection(aliasPw.toCharArray()));
will fail at line 4 with a java.io.IOException if the key store password is wrong, or with a java.security.UnrecoverableKeyException at line 7 if the alias password is wrong.
I want to sign Android app with the same certificate used for the desktop app. I have 3 files - .cer, .p12 and .pfx. Is it possible to use any of those for signing Android app?
Update: I have successfully imported the .cer key (which appears to be X.509-format certificate) into the newly created keystore, but I can't use it for signing. Here's the error message jarsigner gives me:
Certificate chain not found for: [alias]. key must reference a valid
KeyStore key entry containing a private key and corresponding public
key certificate chain.
Perhaps, there's something else I must do with a keystore after importing the certificate to make it valid? Generate a public key or something?
Did you create the keystore with -validity then this issue will appear, remove the -validity. It will work.
keytool -importkeystore -srckeystore certificate/xxxxx.pfx -srcstoretype pkcs12 -destkeystore certificate/xxxxx.keystore -deststoretype JKS **-validity 36500**
Change to
keytool -importkeystore -srckeystore certificate/xxxxx.pfx -srcstoretype pkcs12 -destkeystore certificate/xxxxx.keystore -deststoretype JKS
I had this issue it got sorted because of trying to add validity to a pfx which has valid expiry date.