Only on flutter in android all calls to my server throw the following error
CERTIFICATE_VERIFY_FAILED: certificate has expired(handshake.cc:359))
From the mobile browser my site works, from the PC browser also, and also from the flutter web. Only from android it says certificate expired.
I have checked with SSL Checker and everything is setup correctly. Output of SSL Checker:
$MYDOMAIN resolves to $MYIP
Server Type: Caddy
The certificate should be trusted by all major web browsers (all the correct intermediate certificates are installed).
The certificate was issued by Let's Encrypt.
The certificate will expire in 79 days.
The hostname ($MYDOMAIN) is correctly listed in the certificate.
Does anybody know how to fix this?
just 2 step need for fix error
1.create cutom class extended
class CustomHttpOverrides extends HttpOverrides{
#override
HttpClient createHttpClient(SecurityContext? context){
return super.createHttpClient(context)
..badCertificateCallback = (X509Certificate cert, String host, int port)=> true;
}
}
2.add line to main function
HttpOverrides.global = CustomHttpOverrides();
Related
Recently, I've been testing the certificate pinning implementation provided by OkHttp using version 4.9.0 + Retrofit 2.9.0; And I've noticed that the hash check is not conjunctive but rather disjunctive.
According to the example implementation the certificate chain of publicobject.com:
Peer certificate chain:
sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=: CN=publicobject.com, OU=PositiveSSL
sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=: CN=COMODO RSA Secure Server CA
sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=: CN=COMODO RSA Certification Authority
sha256/lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=: CN=AddTrust External CA Root
If we change the certificate and we do so with the same provider and/or root as before, we would get something like:
Peer certificate chain:
sha256/dklfnskvAAQFvandjfjASAFjvjvg45nbwskdvur5548=: CN=publicobject.com, OU=PositiveSSL
sha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=: CN=COMODO RSA Secure Server CA
sha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=: CN=COMODO RSA Certification Authority
sha256/lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=: CN=AddTrust External CA Root
Only the first hash changes, naturally I would assume that communications with the site should stop working since our implementation now has an incorrect hash, but that is not the case because the other three are the same as before.
Is it my error when creating a new certificate?
Is this the correct behavior or an error?
Is there a way to check for all hashes in the chain to be correct?
There's 4 certificates involved in that particular handshake, and OkHttp is happy if any of them match one of your signatures.
This means you can survive either of these operational events:
changing your certificate authority (your organization public key stays the same)
losing your public key and switching it out (the CA stays the same)
But if you change certificate authorities and you get a new public key, clients won't connect until you update their pins.
My setup:
OkHttp 4.2.2
Conscrypt-android 2.0.0
I'm trying to configure OkHttp to accept:
Built-in commercial server certificates (signed by CAs included in AndroidCAStore)
Internally Conscrypt will then return KeyStore.getInstance("AndroidCAStore")
Non-commercial server certificates (signed by a bundled CA certificate in my app)
I have made both solutions work separately:
To solve (1) I just initialize the trust manager factory with a null key store.
To solve (2) I initialize the trust manager factory using an initialized key store with the bundled CA.
How do I solve both at the same time? I.e. how do i I get a copy of AndroidCAStore and add my certificates to it and use that to initialize the trust manager factory?
This works (exception handling ommitted):
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
// Ommitted: Code to add certificates explictly from file
final KeyStore androidCAStore = KeyStore.getInstance("AndroidCAStore");
androidCAStore.load(null);
final Enumeration<String> androidCAStoreAliases = androidCAStore.aliases();
while (androidCAStoreAliases.hasMoreElements()) {
final String param = androidCAStoreAliases.nextElement();
keyStore.setEntry(param, androidCAStore.getEntry(param, null), null);
}
I'm starting an app on openshift. I've purchased comodo positive ssl from namecheap and followed the instructions to install on openshift. It works fine on desktop browsers but i get the following "not trusted" error on android browsers. I have not tried IOS.
i uploaded following files to openshift:
stylistcity_com.crt
server.key
Other files i have that were not used include:
server.csr
server.pass.key
AddTrustExternalCARoot.crt
PositiveSSLCA2.crt
Any help would be appreciated.
Thanks to #stenwt from the openshift irc channel, It finally work. Here is what i did.
cat mycert.crt cacert.ca > myapp.pem; rhc alias update-cert appname www.domain.com --certificate myapp.pem --private-key myapp.key --passphrase 'mypass'
You have to add the intermediate certificate(s) (the other *.crt) too, because otherwise the browser is not able to verify the certificate chain up to the builtin trusted CA. The only reason that the verification with the desktop browsers succeed is because you already visited sites which use the same intermediate certificates and the browser cached them. If you would use a fresh browser setup (or a new profile with firefox) verification would there fail too.
Had a bit of trouble with the method that worked for OP. For PositiveSSL, on OpenShift, this worked for me:
cat mydomain_com.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > ssl-bundle.crt
rhc alias update-cert myappname www.mydomain.com --certificate ssl-bundle.crt --private-key mydomain_com.key --passphrase 'mypassphrase'
Replace mydomain_com.crt with your main domain cert from Comodo
Replace myappname with your OpenShift app name
Replace www.mydomain.com with your domain alias (the one on OpenShift for your app)
Replace mydomain_com.key with the filename for your private key
Replace mypassphrase with your SSL passphrase
I've opened certificate.ca.crt and certificate.crt, with conTEXT editor,
I copied the contents of certificate.crt and have pasted to the principle of certificate.ca.crt and have saved as certificate.pem, after I've uploaded to OpenShift web console, in SSL certificate *, the first box. Fixed !!
I'm currently developing an Android app that generates an RSA key pair, builds and sends an PKCS#10 certification request to one CA, waits for the CA's response (which contains the certificate-chain including the issued for the end-entity), and then builds the PKCS#12 KeyStore to be installed within the Android KeyStore.
I just show you below some piece of code:
// It removes Android-BC
Security.removeProvider("BC");
// I've tried with SpongyCastle but it also fails.
// I've previously imported BC jars.
Security.addProvider(new BouncyCastleProvider());
KeyStore ks = KeyStore.getInstance("PKCS12","BC");
ks.load(null);
// KeyPair generated by RSA with BC, and certificates obtained from CA.
PrivateKey prvK;
Certificate eeCert, caCert;
PKCS12BagAttributeCarrier caCertBagAttr =
(PKCS12BagAttributeCarrier) caCert;
caCertBagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
new DERBMPString("CA"));
PKCS12BagAttributeCarrier certBagAttr =
(PKCS12BagAttributeCarrier) eeCert;
certBagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
new DERBMPString("EE Certificate"));
certBagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
new SubjectKeyIdentifierStructure(eeCert.getPublicKey()));
Certificate[] chain = new Certificate[2];
chain[1] = caCert;
chain[0] = eeCert;
PKCS12BagAttributeCarrier privBagAttr =
(PKCS12BagAttributeCarrier) prvK;
privBagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
new DERBMPString("EE Certificate Key"));
privBagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
new SubjectKeyIdentifierStructure(eeCert.getPublicKey()));
// Finally, keystore is saved to file.
ks.setKeyEntry("P12", prvK, null, chain);
saveP12File(ks);
The thing is that everything is working OK when I run it on my Windows PC (BouncyCastle 1.49), but that PKCS#12 file created when I run it on Android cannot be used on SSL handshake or signing because Logcat says that it doesn't have any associated PrivateKey.
If I print the full content of the KeyStore on Java after loading the file, it seems that everything is right, but when I use on Android Browser or when I take it and install on Windows, its private key can't be used.
Same code on Android and PC, same version of BC, PKCS#12 doesn't seem to be malformed.
Can anybody help me?
Thanks in advance.
EDIT
I have built a servlet that generates an RSA Key Pair and sends back to my app in PEM format.
All seems work OK:
I can generate a valid (encrypting with public and decrypting test works good) RSA keypair either on Android device or through the external servlet.
I receive both CA and EE certificates from the CA.
I'm able to build a "valid" PKCS12 (I called it valid because it can be read by Android, Windows)
But:
I'm not able to open an SSL channel using the EE certificate as client-certificate for handshake. Either on Windows or Android.
I have uploaded to my Dropbox:
CA certificate
EE certificate issued by the CA
Private Key for the EE certificate
Public Key for the EE certificate
PKCS12 created on Android
Java Android Code
Tested against Tomcat with empty trustStore (doesnt' matter which CA issued client-certificate) unsuccessfully.
Does anybody see something that could explain it?
there. I need to establish https connection with https://free.temafon.ru but I've got CertPathValidatorException on Android 2.3 and below. What have I done.
Grab all certs from https://free.temafon.ru with Firefox.
Import certs in keystore in sequence from temefon certificate to root certificate.
Init ssl context:
final KeyStore keystore = KeyStore.getInstance("BKS");
keystore.load(getResources().openRawResource(R.raw.temafon),
"W0d3Uoa5PkED".toCharArray());
final TrustManager trustManager = new TemafonTrustManager(keystore);
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { trustManager }, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
.getSocketFactory());
Here, I use custom TrustManager, because server sends certs in wrong order.
This code works fine on Android 4.0, but failed on 2.3 with java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. What I'm doing whrong?
I've created a test project, which can be found here.
When you say that you grabbed all the certificates with FireFox, did you also include the root CA?
Most likely, Android 2.3 does not have the root CA installed. Per this link,
In this case, the SSLHandshakeException occurs because you have a CA that isn't trusted by the system. It could be because you have a certificate from a new CA that isn't yet trusted by Android or your app is running on an older version without the CA.