Search code examples
androidcertificatekeystore

How to replace self-signed certificate with ca verified certificate


I created two KeyStores (one for TLS communication and one for encrypt) with self_signed certificates. I created two CSRs and send to server I get verified certificates. How can I replace this self-signed certificates with verified by server?

KeyStore keyTLS;
        byte[] CSRTLSder = new byte[0];
        try {
            keyTLS = KeyStore.getInstance(Constants.AndroidKeyStore);
            keyTLS.load(null);
            Log.d(TAG, String.valueOf("onCreate: check if key is in mobile: " + keyTLS.getKey(KEY_ALIAS_TLS, null)));
            if (keyTLS.getKey(KEY_ALIAS_TLS, null) == null) {
                Calendar notBefore = Calendar.getInstance();
                Calendar notAfter = Calendar.getInstance();
                notAfter.add(Calendar.YEAR, 2);

                KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getApplicationContext())
                        .setAlias(KEY_ALIAS_TLS)
                        .setKeySize(2048)
                        .setSubject(new X500Principal(
                                "CN=Your Company ," +
                                        " O=Your Organization" +
                                        " C=Your Coountry"))
                        .setSerialNumber(BigInteger.ONE)
                        .setStartDate(notBefore.getTime())
                        .setEndDate(notAfter.getTime())
                        .build();


                KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
                generator.initialize(spec);
                generator.generateKeyPair();
            }

            PKCS10CertificationRequest csrTLS = CsrHelper.generateCSRTLS(keyTLS, "AclaasTLS");
        } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException | OperatorCreationException e) {
            e.printStackTrace();
        }

        KeyStore keyEncrypt;
        byte[] CSREncryptder = new byte[0];
        try {
            keyEncrypt = KeyStore.getInstance(Constants.AndroidKeyStore);
            keyEncrypt.load(null);
            Log.d(TAG, String.valueOf("onCreate: check if key is in mobile: " + keyEncrypt.getKey(KEY_ALIAS_ENCRYPT, null)));
            if (keyEncrypt.getKey(KEY_ALIAS_ENCRYPT, null) == null) {
                Calendar notBefore = Calendar.getInstance();
                Calendar notAfter = Calendar.getInstance();
                notAfter.add(Calendar.YEAR, 2);

                KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getApplicationContext())
                        .setAlias(KEY_ALIAS_ENCRYPT)
                        .setKeySize(2048)
                        .setSubject(new X500Principal(
                                "CN=Your Company ," +
                                        " O=Your Organization" +
                                        " C=Your Coountry"))
                        .setSerialNumber(BigInteger.ONE)
                        .setStartDate(notBefore.getTime())
                        .setEndDate(notAfter.getTime())
                        .build();

                KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
                generator.initialize(spec);
                generator.generateKeyPair();
            }

            //Generate CSR in PKCS#10 format encoded in DER
            PKCS10CertificationRequest csrEncrypt = CsrHelper.generateCSREncrypt(keyEncrypt, "AclaasEncrypt");

        } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException | OperatorCreationException e) {
            e.printStackTrace();
        }

When I'm trying to use:

 private void addSignCertificate(byte[] signCertificate, String keyAlias) {
    try {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream in = new ByteArrayInputStream(signCertificate);

        KeyStore keyStore;
        keyStore = KeyStore.getInstance(Constants.AndroidKeyStore);
        keyStore.load( null);

        Certificate signedCertificate;
        signedCertificate = cf.generateCertificate(in);
        Log.d(TAG, keyAlias + " sign certificate: ca= " + ((X509Certificate) signedCertificate).getSubjectDN());
        keyStore.setCertificateEntry(keyAlias, signedCertificate);
    } catch (CertificateException | KeyStoreException | IOException | NoSuchAlgorithmException | UnrecoverableEntryException e) {
        e.printStackTrace();
    }
}

It says that: java.security.KeyStoreException: Entry exists and is not a trusted certificate


Solution

  • SOLVED

    private void addSignCertificate(byte[] signCertificate, String keyAlias) {
            try {
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                InputStream in = new ByteArrayInputStream(signCertificate);
        
                KeyStore keyStore;
                keyStore = KeyStore.getInstance(Constants.AndroidKeyStore);
            keyStore.load( null);
    
            Certificate signedCertificate;
            signedCertificate = cf.generateCertificate(in);
            Log.d(TAG, keyAlias + " sign certificate: ca= " + ((X509Certificate) signedCertificate).getSubjectDN());
            if (keyStore.isKeyEntry(keyAlias )) {
               keyStore.setKeyEntry(
                    ((KeyStore.PrivateKeyEntry) keyStore.getEntry(keyAlias , null)).getPrivateKey(),
                                                        new char[0],
                                                        new Certificate[]{ca})
            } else {
            keyStore.setCertificateEntry(keyAlias, signedCertificate);
            }
        } catch (CertificateException | KeyStoreException | IOException | NoSuchAlgorithmException | UnrecoverableEntryException e) {
            e.printStackTrace();
        }
    }