Android Keystore Error “could not generate key in keystore”

前端 未结 4 1485
情话喂你
情话喂你 2021-02-01 01:59

I get an error trying to generate a key for certain devices. I\'m able to reproduce the error on a Samsung Galaxy Note running 4.4.2.

java.lang.IllegalStateExcep         


        
相关标签:
4条回答
  • 2021-02-01 02:23

    I think this is the right direction: Right click on project > Android Tools > Export Signed Application Package The Export Android Application wizard appears. Select the project I want to export, click Next. The Keystore Selection screen appears.

    0 讨论(0)
  • 2021-02-01 02:24

    If your code is OK then remember that you need to set up a PIN/PW/Fingerprint (Secure unlock) for your device so that the keystore starts functioning. A simple swipe will give such error if you try to generate keypairs.

    0 讨论(0)
  • 2021-02-01 02:30
    public class EncryptionApi18AndAbove{
        private Context context;
        private KeyStore keyStore;
        private static String alias = "alias";
    
        public EncryptionApi18AndAbove(Context context) {
            this.context = context;
            try {
                keyStore = KeyStore.getInstance("AndroidKeyStore");
                keyStore.load(null);
            } catch (Exception e) {
               // bla bla
            }
        }
    
        private String createNewKeys(String alias, Context context) {
            try {
                if (!keyStore.containsAlias(alias)) {
                    Calendar start = Calendar.getInstance();
                    Calendar end = Calendar.getInstance();
                    end.add(Calendar.YEAR, 1);
                    KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
                            .setAlias(alias)
                            .setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
                            .setSerialNumber(BigInteger.ONE)
                            .setStartDate(start.getTime())
                            .setEndDate(end.getTime())
                            .build();
                    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
                    generator.initialize(spec);
                    generator.initialize(spec);
                    generator.generateKeyPair();
                }
            } catch (Exception e) {
                //bla bla
            }
            return alias;
        }
    
        @Override
        public String encrypt(String text) {
            if (text == null || text.length() == 0) {
                return text;
            }
            try {
                KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(createNewKeys(alias, context), null);
                PublicKey publicKey = privateKeyEntry.getCertificate().getPublicKey();
                Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                inCipher.init(Cipher.ENCRYPT_MODE, publicKey);
    
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                CipherOutputStream cipherOutputStream = new CipherOutputStream(
                        outputStream, inCipher);
                cipherOutputStream.write(text.getBytes("UTF-8"));
                cipherOutputStream.close();
    
                return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
            } catch (Exception e) {
                //bla bla
            }
            return text;
        }
    
        @Override
        public String decrypt(String text) {
            if (text == null || text.length() == 0) {
                return text;
            }
            try {
                KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(createNewKeys(alias, context), null);
                PrivateKey privateKey = privateKeyEntry.getPrivateKey();
    
                Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                output.init(Cipher.DECRYPT_MODE, privateKey);
    
                CipherInputStream cipherInputStream = new CipherInputStream(
                        new ByteArrayInputStream(Base64.decode(text, Base64.DEFAULT)), output);
                ArrayList<Byte> values = new ArrayList<>();
                int nextByte;
                while ((nextByte = cipherInputStream.read()) != -1) {
                    values.add((byte) nextByte);
                }
                byte[] bytes = new byte[values.size()];
                for (int i = 0; i < bytes.length; i++) {
                    bytes[i] = values.get(i).byteValue();
                }
                return new String(bytes, 0, bytes.length, "UTF-8");
    
            } catch (Exception e) {
                // bla bla
            }
            return text;
        }
    }
    

    You can use this class . This is works min SDK 18 and above. You can create Android Keystore key , decrypt and encrypt simple text.

    0 讨论(0)
  • 2021-02-01 02:30

    While I don't know the full answer, I can help continue your search. The binder implementation on the other side of mBinder is the native keystore. If I recall fully, it's behavior is to either 1) support key operations at a software level, or 2) delegate to a OEM-provided keymaster library that (presumably) interfaces to the OEM's hardware-backed keystore. More info on this here, here, and here.

    Note: I'll forgo SO's normal policy of pulling the external link content into the answer, since I'm linking you out to three articles that are all >1 page and it seems a bit ridiculous to post a 6-page answer ;-)

    0 讨论(0)
提交回复
热议问题