3

I'm creating an app to control a store, i'm trying to use a local server (192.168.0.56) through an open wifi.

There's a way to my app connect to my server using HTTPS and a self signed certificate?

I'm using retrofit, if its matter.

I tried a lot of tutorials on internet but no success, it always returns this message

Hostname '192.168.0.56' was not verified

to create the certificate i've used this code:

openssl genrsa -out san_server.key 2048
openssl req -new -key san_server.key -out san_server.csr -config openssl.cnf -subj "/C=BR/ST=Mato Grosso do Sul/L=Iguatemi/O=Talski/CN=192.168.0.56"
openssl req -text -noout -in san_server.csr

openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -days 3650 -out rootCA.pem -config openssl.cnf -subj "/C=BR/ST=Mato Grosso do Sul/L=Iguatemi/O=Talski/CN=192.168.0.56"
openssl x509 -req -in san_server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out san_server-rootCA.crt -days 3649
openssl x509 -in rootCA.pem -outform der -out rootCA.der.crt

rootCA.der.crt was also installed in android

And openssl.cnf file:

HOME      = .
RANDFILE    = $ENV::HOME/.rnd

oid_section   = new_oids

[ new_oids ]

[ ca ]
default_ca  = CA_default    # The default ca section

[ CA_default ]

dir   = ./demoCA    # Where everything is kept
certs   = $dir/certs    # Where the issued certs are kept
crl_dir   = $dir/crl    # Where the issued crl are kept
database  = $dir/index.txt  # database index file.
new_certs_dir = $dir/newcerts   # default place for new certs.

certificate = $dir/cacert.pem   # The CA certificate
serial    = $dir/serial     # The current serial number
crlnumber = $dir/crlnumber  # the current crl number
crl   = $dir/crl.pem    # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE  = $dir/private/.rand  # private random number file

x509_extensions = usr_cert    # The extentions to add to the cert

name_opt  = ca_default    # Subject Name options
cert_opt  = ca_default    # Certificate field options

default_days  = 3650     # how long to certify for
default_crl_days= 30      # how long before next CRL
default_md  = sha1      # which md to use.
preserve  = no      # keep passed DN ordering

policy    = policy_match

[ policy_match ]
countryName   = match
stateOrProvinceName = match
organizationName  = match
organizationalUnitName  = optional
commonName    = supplied
emailAddress    = optional

[ policy_anything ]
countryName   = optional
stateOrProvinceName = optional
localityName    = optional
organizationName  = optional
organizationalUnitName  = optional
commonName    = supplied
emailAddress    = optional

####################################################################
[ req ]
default_bits    = 1024
default_keyfile   = privkey.pem
distinguished_name  = req_distinguished_name
attributes    = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert

string_mask = nombstr

req_extensions = v3_req # The extensions to add to a certificate request

[ req_distinguished_name ]
countryName     = Country Name (2 letter code)
countryName_default   = AU
countryName_min     = 2
countryName_max     = 2

stateOrProvinceName   = State or Province Name (full name)
stateOrProvinceName_default = Some-State

localityName      = Locality Name (eg, city)

0.organizationName    = Organization Name (eg, company)
0.organizationName_default  = Internet Widgits Pty Ltd

organizationalUnitName    = Organizational Unit Name (eg, section)

commonName      = Common Name (e.g. server FQDN or YOUR name)
commonName_max      = 64

emailAddress      = Email Address
emailAddress_max    = 64

[ req_attributes ]
challengePassword   = A challenge password
challengePassword_min   = 4
challengePassword_max   = 20

unstructuredName    = An optional company name

[ usr_cert ]

basicConstraints=CA:FALSE

nsComment     = "OpenSSL Generated Certificate"

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

[ v3_req ]

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = IP:192.168.0.56

[ v3_ca ]

subjectKeyIdentifier=hash

authorityKeyIdentifier=keyid:always,issuer:always

basicConstraints = CA:true

[ crl_ext ]

authorityKeyIdentifier=keyid:always,issuer:always

[ proxy_cert_ext ]

basicConstraints=CA:FALSE

nsComment     = "OpenSSL Generated Certificate"

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always

proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo

then created a TrustStore as explained in this https://stackoverflow.com/a/24007536/1001133

Community
  • 1
  • 1
talski
  • 293
  • 2
  • 11

1 Answers1

5

If you're using retrofit you can create a custom HTTP client (OkhttpClient/ApacheClient etc...) in order to configure your client and bind it to the retrofit client.

        OkHttpClient okHttpClient = new OkHttpClient();

        HostnameVerifier hostNameVerifier = new X509HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                try {
                    verifyHost(hostname);
                    return true;
                } catch (SSLException e) {
                    e.printStackTrace();
                    return false;
                }
            }

            @Override
            public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
                verifyHost(host);
            }

            @Override
            public void verify(String host, X509Certificate cert) throws SSLException {
                verifyHost(host);
            }

            @Override
            public void verify(String host, SSLSocket ssl) throws IOException {
                verifyHost(host);
            }

            private void verifyHost(String sourceHost) throws SSLException {
                if (!hostName.equals(sourceHost)) { // THIS IS WHERE YOU AUTHENTICATE YOUR EXPECTED host (IN THIS CASE 192.168.0.56)
                    throw new SSLException("Hostname '192.168.0.56' was not verified");
                }
            }
        };

        okHttpClient.setHostnameVerifier(hostNameVerifier);             
        OkClient okClient = new OkClient(okHttpClient);

         RestAdapter restAdapter = new RestAdapter.Builder()
        **.setClient(okClient)** //this is where u bind the httpClient
        .build(); //make sure you specify endpoint, headerInterceptor etc ...

Hope this helps !

jadkachmar
  • 118
  • 10