Friday, 29 October 2021

How to reproduce or solve KeyStoreException?

Get crash with next description:

Caused by java.security.UnrecoverableKeyException: Failed to obtain X.509 form of public key at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:263) at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:303) at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(AndroidKeyStoreProvider.java:324) at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(AndroidKeyStoreProvider.java:388) at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:105) at java.security.KeyStore.getKey(KeyStore.java:1062) at com.mandarine.sai.sdk.tools.keystore.KeyStoreManager.getKeyPair(KeyStoreManager.java:117) at com.mandarine.sai.sdk.tools.keystore.KeyStoreManager.deleteKeyPairs(KeyStoreManager.java:222) at com.mandarine.sai.features.authorizations.common.ConnectionKeyBuilderKt.collectConnectionsAndKeys(ConnectionKeyBuilderKt.java:73) at com.mandarine.sai.features.authorizations.common.ConnectionKeyBuilderKt.collectConnectionsAndKeys(ConnectionKeyBuilderKt.java:41) at com.mandarine.sai.features.authorizations.list.AuthorizationsListViewModel.(AuthorizationsListViewModel.java:79) at com.mandarine.sai.app.ViewModelsFactory.create(ViewModelsFactory.java:102)

KeyStoreException: Invalid key blob

Caused by android.security.KeyStoreException: Invalid key blob at android.security.KeyStore.getKeyStoreException(KeyStore.java:1301) at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:265) at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:303) at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(AndroidKeyStoreProvider.java:324) at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(AndroidKeyStoreProvider.java:388) at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:105) at java.security.KeyStore.getKey(KeyStore.java:1062) at com.mandarine.sai.sdk.tools.keystore.KeyStoreManager.getKeyPair(KeyStoreManager.java:117) at com.mandarine.sai.sdk.tools.keystore.KeyStoreManager.deleteKeyPairs(KeyStoreManager.java:222) at com.mandarine.sai.features.authorizations.common.ConnectionKeyBuilderKt.collectConnectionsAndKeys(ConnectionKeyBuilderKt.java:73) at com.mandarine.sai.features.authorizations.common.ConnectionKeyBuilderKt.collectConnectionsAndKeys(ConnectionKeyBuilderKt.java:41) at com.mandarine.sai.features.authorizations.list.AuthorizationsListViewModel.(AuthorizationsListViewModel.java:79) at com.mandarine.sai.app.ViewModelsFactory.create(ViewModelsFactory.java:102) at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187) at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) at com.mandarine.sai.features.authorizations.list.AuthorizationsListFragment.setupViewModel(AuthorizationsListFragment.java:119) at com.mandarine.sai.features.authorizations.list.AuthorizationsListFragment.onCreate(AuthorizationsListFragment.java:65) at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684)

Here is code:

fun collectConnectionsAndKeys(
    repository: ConnectionsRepositoryAbs,
    keyStoreManager: KeyStoreManagerAbs
): Map<ConnectionID, ConnectionAndKey> {
    return repository.getAllActiveConnections().mapNotNull {
        it.getPrivateKeyForConnection(keyStoreManager)
    }.toMap()
}




  /**
     *  Get related private key for connection
     *
     *  @param connection Connection
     *  @return ConnectionAndKey
     */
    override fun createConnectionAndKeyModel(connection: ConnectionAbs): ConnectionAndKey? {
        return getKeyPair(connection.guid)?.private?.let { key ->
            ConnectionAndKey(connection, key)
        }
    }

    /**
     * Get RSA key pair by the given alias
     *
     * @param alias - the alias name
     * @return KeyPair object
     */
    override fun getKeyPair(alias: String?): KeyPair? {
        val keyAlias = alias ?: return null
        val store = androidKeyStore ?: return null
        return (store.getKey(keyAlias, null) as? PrivateKey)?.let { privateKey ->
            val publicKey: PublicKey? = store.getCertificate(keyAlias).publicKey
            KeyPair(publicKey, privateKey)
        }
    }

UPDATE:

So i write something like this:

override fun getKeyPair(alias: String?): KeyPair? {
    return try {
        val keyAlias = alias ?: return null
        val store = androidKeyStore ?: return null
        (store.getKey(keyAlias, null) as? PrivateKey)?.let { privateKey ->
            val publicKey: PublicKey? = store.getCertificate(keyAlias).publicKey
            KeyPair(publicKey, privateKey)
        }
    } catch (e: UnrecoverableKeyException) {
        null
    } catch (e: Exception) {
        Timber.e(e)
        null
    }
}

But i don't understand why is my android keystore currently blocked on my XIAOMI phone? I have seen similar problems here and here, but deleting the key from keystore is not my solution.



from How to reproduce or solve KeyStoreException?

How to save website for offline in flutter

I am having some trouble saving the website inside the flutter app. I have tried using the cache method and savewebarchive method for the inappwebview. The issue with the method is that it is not saving the full content of the website. It is only saving HTML and CSS files.

I want to save the whole website with all the content like HTML, CSS, js, font files, Images and store it inside the flutter app. I have gone through a few plugins but none of them were helpful.

I am looking for the same functionality as httrack.

Any right direction would be appriciated.



from How to save website for offline in flutter

Thursday, 28 October 2021

How can I pass a value to init methods on import?

Let's assume I have component like this:

'use strict';

export default () => ({
    selected: false,
    init(selectedIndex: -1)
    {

    }

});

and I import it like this (using AlpineJS 3):

import Alpine from 'alpinejs'

window.Alpine = Alpine

window.Components = {};

import Tab from "./components/Tab";
window.Components.Tab = Tab;

Alpine.start();

How can I now pass value to init method?

When I have:

<div x-data="Components.Tab(0)">...</div>

value is obviously not passed to init method.

Although there is info in docs how to register component from a bundle and info how to pass initial parameters, there is no info how to pass initial parameters to component registered from a bundle



from How can I pass a value to init methods on import?