Quantcast
Channel: Active questions tagged https - Stack Overflow
Viewing all articles
Browse latest Browse all 1854

NanoHTTPD server on Embedded Android TV: HTTP works but HTTPS shows blank page after authentication

$
0
0

I’m working on an embedded Android TV project. I’m using NanoHTTPD as the web server. The server hosts a simple web page that can be accessed from a browser by entering the IP address of the TV.

Here’s how it works with HTTP:

  • I open the browser and enter the TV’s IP address (e.g., http://192.168.1.x:8080).
  • A login prompt appears (Basic/Digest Auth).
  • After entering the correct credentials, the page is displayed successfully.

However, when I switch to HTTPS:

  • I access the page at https://192.168.1.x:8443.
  • The login prompt still appears.
  • After entering correct credentials, the page remains blank — it does not load, and no content is displayed.
  • There are no errors in ADB logs or browser console.

Additional Info:

Target device: Android 9-based embedded TV

Browser: Chrome/Edge (tested from a PC in the same network)

SSL: Self-signed certificate

Authentication: Basic and Digest (tested both)

No errors in ADB logcat or NanoHTTPD logs

Here is what I’ve already done:

  • I’ve created a self-signed certificate using OpenSSL.
  • I’ve configured NanoHTTPD to use SSL with the certificate.
  • The server starts without errors and listens on the HTTPS port.
  • I made sure that the MIME types and response structure are the same as HTTP.
  • The credentials are accepted correctly; the problem is after authentication.

What I’d like to ask:

  • Could you please look at the code snippets below and let me know if there are any mistakes or missing configurations in the HTTPS setup?
  • Do I need to handle HTTPS requests differently in NanoHTTPD compared to HTTP?
  • Could the problem be related to how the browser handles the self-signed certificate?
    public HTTPServer(Context context, String serverPath) {        super(SERVER_HOSTNAME, SERVER_PORT);        this.context = context;        this.serverPath = serverPath;        readCredentials();        try {            String ipAddress = getDeviceIpAddress();            char[] ksPassword = "password".toCharArray();            String keystoreFilePath = "/odm/etc/tvconfig/crestron/keystore.p12";            File keystoreDir = new File("/odm/etc/tvconfig/crestron/");            if (!keystoreDir.exists()) {                boolean created = keystoreDir.mkdirs();                if (created) {                    Log.d(TAG, "Keystore created: " + keystoreDir.getAbsolutePath());                } else {                    Log.e(TAG, "Keystore couldn't be created: " + keystoreDir.getAbsolutePath());                }            }            File keystoreFile = new File(keystoreFilePath);            KeyStore loadedKeyStore;            if (!keystoreFile.exists() || keystoreFile.length() == 0) {                Log.d(TAG, "Keystore is non-existing or blank, creating a new one...");                loadedKeyStore = createDynamicKeyStore(ipAddress, String.valueOf(ksPassword), keystoreFilePath);                Log.d(TAG, "Keystore saved at  '" + keystoreFilePath);            }            loadedKeyStore = KeyStore.getInstance("PKCS12");            try (FileInputStream fis = new FileInputStream(keystoreFile)) {                 loadedKeyStore.load(fis, ksPassword);                Log.d(TAG, "Keystore successfully loaded from '" + keystoreFilePath);            }            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());            kmf.init(loadedKeyStore, ksPassword);            SSLContext sslContext = SSLContext.getInstance("TLS");            sslContext.init(kmf.getKeyManagers(), null, null);            makeSecure(sslContext.getServerSocketFactory(), null);            Log.d(TAG, "HTTPS is secured");        } catch (Exception e) {            Log.e(TAG, "HTTPServer error: " + e.getMessage(), e);        }        generateNonce();    }// generating a generic certificate file:    public KeyStore createDynamicKeyStore(String ip, String password, String filePath) throws Exception {        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");        keyPairGenerator.initialize(2048);        KeyPair keyPair = keyPairGenerator.generateKeyPair();        long now = System.currentTimeMillis();        Date startDate = new Date(now - 3600000L);        Date endDate = new Date(now + 365L * 24 * 3600 * 1000);        X500Name issuer = new X500Name("CN=" + ip);        X500Name subject = issuer;        BigInteger serial = BigInteger.valueOf(now);        GeneralName ipName = new GeneralName(GeneralName.iPAddress, ip);        GeneralNames subjectAltName = new GeneralNames(ipName);        ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").build(keyPair.getPrivate());        X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(            issuer, serial, startDate, endDate, subject, keyPair.getPublic());        certBuilder.addExtension(Extension.subjectAlternativeName, false, subjectAltName);        X509Certificate certificate = new JcaX509CertificateConverter().getCertificate(certBuilder.build(signer));        KeyStore keyStore = KeyStore.getInstance("PKCS12");        keyStore.load(null, null);         keyStore.setKeyEntry("dynamickey", keyPair.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{certificate});        try (FileOutputStream fos = new FileOutputStream(filePath)) {        keyStore.store(fos, password.toCharArray());        Log.d(TAG, "KeyStore successfully saved at '" + filePath);        }        return keyStore;    }

Viewing all articles
Browse latest Browse all 1854

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>