Android Keystore Error “could not generate key in keystore”

前端 未结 4 1499
情话喂你
情话喂你 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: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 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.

提交回复
热议问题