androidencryptionrsaprivate-keyandroid-keystore

Cannot convert PrivateKey to String


I want to convert an private key to an String so that user can store it in hard state .

i tried to convert the private key using Base64 but it gives me error stating privateKey.getEncoded() is null

So i tried before Base64 and again i got null .

public String newKey() throws
            NoSuchAlgorithmException,
            NoSuchProviderException,
            InvalidAlgorithmParameterException, KeyStoreException, CertificateEncodingException, UnrecoverableEntryException {

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, KEYSTORE);
        KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec
                .Builder(alias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
                .setEncryptionPaddings(PADDING)
                .build();

        keyPairGenerator.initialize(keyGenParameterSpec);
        PrivateKey key = keyPairGenerator.generateKeyPair().getPrivate();

        KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,null);
        String a = privateKeyEntryToString(entry,key);
        //  java.util.Base64.getDecoder().decode(entry)
        //  Log.d("tag",entry);


        Log.d("tag", "done in new Key returning keypublic");
        return a;
       // return keyPairGenerator.generateKeyPair().getPublic();

    }
    private String privateKeyEntryToString(KeyStore.PrivateKeyEntry privateKeyEntry,PrivateKey key) throws CertificateEncodingException {

 Certificate certificate = privateKeyEntry.getCertificate();
        if (key.getEncoded().length == 0){ // but here we get exception that it is null.
            return "its empty";
        }
        
        

        // Convert PrivateKey and Certificate to String
        String privateKeyString = Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
        String certificateString = Base64.encodeToString(certificate.getEncoded(), Base64.DEFAULT);

        // Combine both strings with a separator for later use
        return privateKeyString + "-----BEGIN CERTIFICATE-----\n" + certificateString;

Stack trace :

FATAL EXCEPTION: main
Process: com.leo.nopasswordforyou, PID: 9525
java.lang.NullPointerException: Attempt to get length of null array

Solution

  • the thing is i am getting Private key from keyPairGenerator.generateKeyPair() , so does that mean after generating keyPair , it stores them in KeyPair and when prompted to receive, it forwards the keystore's key . eg : keyPairGenerator.generateKeyPair().getPrivate();

    I think that this is where the misconception lies. The keys are generated within the Android key store, they are not imported into it. And the Android key store does protect the value of the private key.

    If you want to create the keys in software then you can simply try and remove the badly named KEYSTORE argument entirely; by default the Android provider won't be used. And yes, this is a bit of a weird API, you can probably not just set it to null and remain compatible; you may also have to remove the NoSuchProviderException from any catch clause if you do.