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();
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
...
How to generate signature in Flutter (azure connection, msal)?
"redirect_uri" : "msauth://<YOUR_PACKAGE_NAME>/<YOUR_BASE64_URL_ENCODED_PACKAGE_SIGNATURE>",
What exactly is package signature and how to generate it in Flutter?
I use this library:
https://pub.dev/packages/flutter_azure_b2c
EDIT:
Should I use only keytool to generate?
echo y | keytool -genkeypair -dname "cn=Jones, ou=JavaSoft, o=Sun, c=PL" -alias business -keypass kpi135 -keystore C:/Workspace/android.js -storepass ab987c -validity 20000
I use this one:
Generate SHA-1 for Flutter/React-Native/Android-Native app
but it is much longer than usual code I saw.
I have SHA1 encoded and it is longer, is it correct to use?
i.e.
my is like :
RTE6ASD6MDk6ODM6RUY6NjY6N0I6RjY6MkE6M0U6QzA6MTU6QzI6NkU6QkI6MTE6NEU6Qjc6MTc6MzI=
correct length
M61nf%2CaH69kCSmFY1ejcX83rNNc%3D
I get the title and the text below when I try and fail to build an .aab file using flutter build appbundle:
java.util.concurrent.ExecutionException: java.lang.RuntimeException: jarsignerfailed with exit code 1 :
jarsigner: Certificate chain not found for: keystore. keystore must reference a valid KeyStore key entry containing a private key and corresponding public key certificate chain.
I had to reset my signing key. The google developer support had me generate a new .jks file with the following command line which I ran from within my project folder:
keytool -genkeypair -alias upload -keyalg RSA -keysize 2048 -validity 9125 -keystore keystore.jks
He then instructed me to convert this file into a .pem file using this command:
keytool -export -rfc -alias upload -file upload_certificate.pem -keystore keystore.jks
I then emailed him the upload_certificate.pem file. I immediately noticed that the keystore.jks file was red in the sidebar and I get this upon clicking on it:
"The file 'keystore.jks' is not associated with any file type. Please define the association:"
The .pem file is also red, but clicking on it shows the text that makes up the key.
Do I need to reset the signing key again and do something different? Is there a way to fix the issue causing this error?
As dumb as this may sound, I spent 24 hours on this and all I had to was enter flutter clean
You have keyAlias=keystore in your key.properties while it looks like the alias you created is named upload (see in your keytool export command).
Repleace with keyAlias=upload and that should work if your password is correct.
I am having trouble using SSL, as I am getting the following error related to my keystore (self-created and self-signed using keytool per: http://developer.android.com/tools/publishing/app-signing.html):
08-14 20:55:23.044: W/System.err(5430): java.io.IOException: Wrong
version of key store. 08-14 20:55:23.060: W/System.err(5430): at
org.bouncycastle.jce.provider.JDKKeyStore.engineLoad(JDKKeyStore.java:812)
...
The error thrown in the JDKKeyStore.java class arises in the following code:
Blockquote
From JDKKeyStore.java:
if (version != STORE_VERSION)
{
if (version != 0)
{
throw new IOException("Wrong version of key store.");
}
}
Blockquote
In this case STORE_VERSION = 1, and my version=3 based on reading the details of the certificate held by the keystore I have created. I do not know how to generate a keystore containing a version=1 certificate.
I found this answer helpful:
wrong version keystore when doing https call
however it calls for creating the keystore using the following parameters:
-storetype BKS
-provider org.bouncycastle.jce.provider.BouncyCastleProvider
-providerpath /path/to/bouncycastle.jar
However, when I try to create the keytool (using the terminal app on Mac) using these parameters:
keytool -genkeypair -v -alias androiddebugkey -keyalg RSA -keysize
2048 -validity 10000 -keypass android -keystore
/Users/djames/dropbox/bc146keystore/debug.keystore -storepass android
-providerclass org.bouncycastle.jce.provider.BouncyCastleProvider –providerpath /Users/djames/dropbox/bc146keystore/
(where /Users/djames/dropbox/bc146keystore/ is the path to the bouncy castle jar: bcprov-jdk16-146.jar)
I get the following error:
keytool error: java.lang.RuntimeException: Usage error, ?providerpath
is not a legal command java.lang.RuntimeException: Usage error,
?providerpath is not a legal command at
sun.security.tools.KeyTool.parseArgs(KeyTool.java:375) at
sun.security.tools.KeyTool.run(KeyTool.java:171) at
sun.security.tools.KeyTool.main(KeyTool.java:166)
I do not understand what this is telling me. If I use: keytool -help it tells me that the following are valid options for the -genkeypair option:
-genkeypair [-v] [-protected]
[-alias ]
[-keyalg ] [-keysize ]
[-sigalg ] [-dname ]
[-validity ] [-keypass ]
[-keystore ] [-storepass ]
[-storetype ] [-providername ]
[-providerclass [-providerarg ]] ...
[-providerpath ]
But in the Oracle docs java version 6 that I am using
(http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html)
it tells me that these are the options:
-genkeypair {-alias alias} {-keyalg keyalg} {-keysize keysize} {-sigalg sigalg} [-dname dname] [-keypass keypass] {-validity valDays}
{-storetype storetype} {-keystore keystore} [-storepass storepass]
{-providerClass provider_class_name {-providerArg provider_arg}} {-v}
{-protected} {-Jjavaoption}
which does not include the -providerpath option. Why the discordance?
(If I do not use the -providerpath option, then I get an unknown class exception at the option: "-providerclass org.bouncycastle.jce.provider.BouncyCastleProvider"...)
When I google: keytool -providerpath
I get nothing helpful to resolve this.
I am not sure how to solve my keystore version problem without solving my keytool problem. Any suggestions appreciated.
Jim
(Mac OSX 10.6.8 if relevant)
My problem was using a version of bouncy castle that was too new. I had to use 146 - any later and it gave me this error.
I was able to get past this problem with the version of keystore. see: keytool error when creating BKS keystore: providerpath is not a legal command
The version mismatch is for the key store version, not the certificate version (which should have the value 2 for a v3 X.509 certificate).
What version of the JDK did you use keytool from? Did you specify a full path to the command, or use what was in your PATH? Are you sure that you are using JKS key stores, and not JCEKS stores?
In order to complete Ryan answer as I had to dig in to find out how to generate a BKS with Bouncy Castle 1.46, you can use Portecle to generate the BKS.
Download Boucycastle Provider 1.46
Install or unzip it.
Replace bcprov.jar in your Portecle install directory (example: C:\Program Files (x86)\Portecle\bcprov.jar). Same naming is required.
Restart Portecle and generate your BKS truststore.
This explained here.
Edit:
Since Portecle 1.8, you can use BKS-V1 type to generate your truststore without to replace bcprov.jar.
You can select it after clicking on New keystore or change the type via the menu Tools -> Change KeyStore Type.
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.