I am performing Passive Authentication of passport chip using jmrtd.
I am able to verify signature using DSC(Digital Singing Certificate).
But I am not able to verify DSC using CSC (Country Signing Certificate).
Please provide some approach, thanks in advance.
Probably way too late for you, but in case anyone else runs in to this :)
To do that you basically need to create a trust store with the CSCs. Basically they are just certificate authorities and needs to be treated as such.
First step is to create a PKCS12 containing all the CSCs you want/need, this for some reason can't be done using OpenSSL, but fortunately keytool is your friend: keytool importing multiple certificates in single file
Next up is creating a trust store, e.g., by following this example: https://stackoverflow.com/a/6379434/1441857
The keystore needed for the step above is created as follows:
private KeyStore createStore(InputStream pkcs12Stream) {
final KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(pkcs12Stream, "password".toCharArray());
return keyStore;
}
finally you can simply validate by using your trustmanager(s) (there's actually just one, as expected), following the first answer I linked. The authType parameter seems to be "RSA_EXPORT", haven't figured why yet.
I think that should do the trick :)
Related
I'm noob with SSL.
I have implemented SSL with cerbot/letscrypt [nginx/Ubuntu 14.04]. I had also done public key SSL pinning on the android app. Everything is in production and working fine.
But once the certificate expires i want to renew certificate with the same key to prevent any forceful app update.
Please let me know is there any way i can work around.
Thank You in advance.
I am looking for the same type of solution for Traefik, and as I mention in my question I think it's possible for Certbot, at least from reading their --help.
So if you run:
docker run --rm -it certbot/certbot --help all
You will find:
--reuse-key When renewing, use the same private key as the existing certificate. (default: False)
I have this scenario where my App needs to make requests towards a secure server (NON http(s), actually it is about SIP protocol but the question should apply to any non http(s) protocol), and I need be able to tell if the server is considered trusted, based on the System Default Trusted certificates installed in my Android device's keystore.
The problem is that after checking all the APIs Android provides for certificates (like KeyStore, KeyChain, etc) I haven't been able to find a solution.
Seems that each app, even though it can gain access to the System Default keystore of the device, it can only access it's own resources, not global, even when we are talking about TrustedCertificateEntry-type entries.
Is there anything I'm missing here?
Seems like a pretty valid use case for non-https authentication
Best regards,
Antonis
Finally, managed to find a way to do this, so let me share in case this can be useful to others. Turns out Android gives access to system wide trusted certificates. The detail here (and the reason it didn't work for me previously) was the keystore 'type' identifier that I used:
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
Which I believe was trying to find actual keys, which off course shouldn't be shared. So after some digging I found that there's a separate type, AndroidCAStore, which did the trick for me. So here's a working code excerpt, that just prints out certificates:
try {
KeyStore ks = KeyStore.getInstance("AndroidCAStore");
ks.load(null);
try {
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
Certificate cert = ks.getCertificate(aliases.nextElement());
Log.e(TAG, "Certificate: " + cert.toString());
}
}
catch(Exception e) {
e.printStackTrace();
}
}
catch (IOException|NoSuchAlgorithmException|KeyStoreException|CertificateException e) {
e.printStackTrace();
}
I have a custom SSL Root CA for the web and I want to be able to install it on android devices. If I download it it says "No certificate to install". How can I configure the certificate to work using openSSL or another tool? I have done some googling and some sites say that I should covert it to a .pfx but this involves giving the user my private key and ruining the security.
If you want to add your certificate to Android KeyChain (it is possible since ICS) you need to provide X509Certificate (.crt, .pem, etc) or PKCS12 (.pfx) file.
You have to call install intent from KeyChain class.
According to documentation: http://developer.android.com/reference/android/security/KeyChain.html#createInstallIntent()
Returns an Intent that can be used for credential installation. The
intent may be used without any extras, in which case the user will be
able to install credentials from their own source.
Alternatively, EXTRA_CERTIFICATE or EXTRA_PKCS12 maybe used to specify
the bytes of an X.509 certificate or a PKCS#12 key store for
installation. These extras may be combined with EXTRA_NAME to provide
a default alias name for credentials being installed.
When used with startActivityForResult(Intent, int), RESULT_OK will be
returned if a credential was successfully installed, otherwise
RESULT_CANCELED will be returned.
However
In my opinion what you really want to do is to include your X509Certificate along with your application so you can estabilish secure SSL connection without user knowledge which will work on all devices.
In order to do that, you will have to create put your X509Certificate in application (as PEM string, .crt file .der file or inside BouncyCastle KeyStore) and initialize SSLContext with it. After you do that you can get SSLSocketFactory which you can use with you http client.
More information about that:
https://developer.android.com/training/articles/security-ssl.html
I came across (inherited) the following code:
String ksType = KeyStore.getDefaultType();
KeyStore ks = KeyStore.getInstance(ksType);
ks.load(null, null);
SSLSocketFactory sockFactory = new SSLSocketFactory(ks);
I am confused by the call to the KeyStore load method. What keystore is this code using? I looked at the KeyStore documentation and as far as I can tell this is legitimate.
However, the code does not work. The app takes a URL for the server to connect to. The app throws javax.net.ssl.SSLPeerUnverifiedException: No peer certificate errors - even if the site has a valid SSL certificate.
Debugging, I added the following line:
Log.v(TAG,"ks has " + String.valueOf(ks.size()) + " entries.");
to get the number of items in the keystore. It returns zero.
I feel like I am grossly misunderstanding something about KeyStores.
Should this code work? What is it supposed to do?
EDIT
Based on how the code is being used (to authenticate websites) I believe it is being used as a truststore, not a keystore. The SSLSocketFactory that is being used from org.apache.http.conn.ssl. Looking at the resources for the app, there does not appear to be a keystore file included in the app. Puzzling to me.
It might work if it was being used as a keystore, but so would 'null'. It wouldn't work if it was being used as a truststore. Can you post the constructor of SSLSocketFactory that is being called?
EDIT: Any SSL client needs a non-empty truststore to be secure. The one supplied with Java is sufficient for most purposes.
I am after a solution which would enable me to use the in-build keystore and StrictHostnameVerifier but would allow me to obtain the X590CertificateChain (either once connected or post handshake) so I can perform some additional checks (specifically I want to verify the root public key is the one I expected).
The examples I have investigated are mainly around overriding the behaviour (i.e. by replacing the socket factory or hostname checker with ones which don't do anything) and I am struggling with the differences between the android and other java implementations.
The reason I don't want to bundle a keystore (aside from having to use bouncycastle instead of jks) is that I don't want to package the intermediate CA cert with the app as this will create a certificate management problem sooner.
Many thanks in advance for any comments.
Ideally, this should be done at runtime. Bundling the certificate might be redundant as well, when some devices might already have that certificate installed.
Normally, your approach should be this.
Try connecting to the server.
If certificate is not installed, you will get a certificate exception. Catch it, extract the public certificate, save it, by creating a keystore on the fly.
While making new connections, use this keystore to initialize your SSL context.