本文介绍了KeyPairGeneratorSpec替换KeyGenParameterSpec.Builder等效 - Keystore操作失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 以下方法已弃用 KeyPairGenerator generator = KeyPairGenerator.getInstance(RSA,AndroidKeyStore); KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(this) .setAlias(alias) .setSubject(new X500Principal(CN = Sample Name,O = Android Authority)) .setSerialNumber(BigInteger.ONE) .setStartDate(start.getTime()) .setEndDate(end.getTime()) .build(); generator.initialize(spec); 我来的替换看起来像这样 generator.initialize(new KeyGenParameterSpec.Builder (别名,KeyProperties.PURPOSE_SIGN) .setDigests(KeyProperties.DIGEST_SHA256) .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1) .build()); 尽管我可以使用它来生成密钥对密码并加密该值,但我无法解密它 public void encryptString(String alias){ try { KeyStore.PrivateKeyEntry privateKeyEntry = KeyStore.PrivateKeyEntry)keyStore.getEntry(别名,null); RSAPublicKey publicKey =(RSAPublicKey)privateKeyEntry.getCertificate()。getPublicKey(); String initialText = startText.getText()。toString(); if(initialText.isEmpty()){ Toast.makeText(this,在初始文本小部件中输入文本,Toast.LENGTH_LONG).show(); return; } //Security.getProviders(); 密码inCipher = Cipher.getInstance(RSA / ECB / PKCS1Padding,AndroidKeyStoreBCWorkaround); inCipher.init(Cipher.ENCRYPT_MODE,publicKey); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); CipherOutputStream cipherOutputStream = new CipherOutputStream( outputStream,inCipher); cipherOutputStream.write(initialText.getBytes(UTF-8)); cipherOutputStream.close(); byte [] vals = outputStream.toByteArray(); encryptedText.setText(Base64.encodeToString(vals,Base64.DEFAULT)); } catch(Exception e){ Toast.makeText(this,Exception+ e.getMessage()+occured,Toast.LENGTH_LONG).show(); Log.e(TAG,Log.getStackTraceString(e)); } } public void decryptString(String alias){ try { KeyStore.PrivateKeyEntry privateKeyEntry =(KeyStore.PrivateKeyEntry)keyStore.getEntry别名,null); 密码输出= Cipher.getInstance(RSA / ECB / PKCS1Padding,AndroidKeyStoreBCWorkaround); output.init(Cipher.DECRYPT_MODE,privateKeyEntry.getPrivateKey()); String cipherText = encryptedText.getText()。toString(); CipherInputStream cipherInputStream = new CipherInputStream( new ByteArrayInputStream(Base64.decode(cipherText,Base64.DEFAULT)),输出); ArrayList< Byte> values = new ArrayList<>(); int nextByte; while((nextByte = cipherInputStream.read())!= -1){ values.add((byte)nextByte); } byte [] bytes = new byte [values.size()]; (int i = 0; i< bytes.length; i ++){ bytes [i] = values.get(i).byteValue(); } String finalText = new String(bytes,0,bytes.length,UTF-8); decryptptedText.setText(finalText); } catch(Exception e){ Toast.makeText(this,Exception+ e.getMessage()+occured,Toast.LENGTH_LONG).show(); Log.e(TAG,Log.getStackTraceString(e)); } 在 decrypt 方法,以下命令失败: 密码输出= Cipher.getInstance(RSA / ECB / PKCS1Padding,AndroidKeyStoreBCWorkaround) ; output.init(Cipher.DECRYPT_MODE,privateKeyEntry.getPrivateKey()); 与 java.security.InvalidKeyException:密钥库操作失败 我认为它与KeyGenParamaterSpec.Builder具有不正确的条件,类似于加密密码类型是不正确的字符串,在解密功能中也是一样的。 但是这可以追溯到新的KeygenParameterSpec.Builder使用旧的deprecated方法允许我加密和解密。 如何修复?解决方案由于Alex提到一个缺失的部分是 KeyProperties.PURPOSE_DECRYPT 另一个是 setSignaturePaddings 而不是你必须使用 setEncryptionPaddings 方法。以下是示例代码片段。 新的KeyGenParameterSpec.Builder(ALIAS,KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)。 setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) //其他选项 .build() 有关详细信息,请参阅文档。 The following method is deprecatedKeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(this) .setAlias(alias) .setSubject(new X500Principal("CN=Sample Name, O=Android Authority")) .setSerialNumber(BigInteger.ONE) .setStartDate(start.getTime()) .setEndDate(end.getTime()) .build();generator.initialize(spec);The replacement I came upon looks like thisKeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");generator.initialize(new KeyGenParameterSpec.Builder (alias, KeyProperties.PURPOSE_SIGN) .setDigests(KeyProperties.DIGEST_SHA256) .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1) .build());Although I am able to use this to generate a keypair entry and encrypt the value, I am unable to decrypt it public void encryptString(String alias) { try { KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null); RSAPublicKey publicKey = (RSAPublicKey) privateKeyEntry.getCertificate().getPublicKey(); String initialText = startText.getText().toString(); if(initialText.isEmpty()) { Toast.makeText(this, "Enter text in the 'Initial Text' widget", Toast.LENGTH_LONG).show(); return; } //Security.getProviders(); Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); inCipher.init(Cipher.ENCRYPT_MODE, publicKey); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); CipherOutputStream cipherOutputStream = new CipherOutputStream( outputStream, inCipher); cipherOutputStream.write(initialText.getBytes("UTF-8")); cipherOutputStream.close(); byte [] vals = outputStream.toByteArray(); encryptedText.setText(Base64.encodeToString(vals, Base64.DEFAULT)); } catch (Exception e) { Toast.makeText(this, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show(); Log.e(TAG, Log.getStackTraceString(e)); } }public void decryptString(String alias) { try { KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null); Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey()); String cipherText = encryptedText.getText().toString(); CipherInputStream cipherInputStream = new CipherInputStream( new ByteArrayInputStream(Base64.decode(cipherText, 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(); } String finalText = new String(bytes, 0, bytes.length, "UTF-8"); decryptedText.setText(finalText); } catch (Exception e) { Toast.makeText(this, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show(); Log.e(TAG, Log.getStackTraceString(e)); }in the decrypt method, the following command fails: Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());withjava.security.InvalidKeyException: Keystore operation failedI think it has to do with the KeyGenParamaterSpec.Builder has incorrect conditions, similarly that the encrypt Cipher types are incorrect strings, same thing in the decrypt function.But this can all be traced back to the use of the new KeygenParameterSpec.Builder, as using the older deprecated method allows me to encrypt and decrypt.How to fix? 解决方案 As Alex mentioned one missing piece is KeyProperties.PURPOSE_DECRYPT other one is setSignaturePaddings instead for that you have to use setEncryptionPaddings method. Here is the sample snippet. new KeyGenParameterSpec.Builder(ALIAS, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) // other options .build()Refer documentation for more information. 这篇关于KeyPairGeneratorSpec替换KeyGenParameterSpec.Builder等效 - Keystore操作失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-22 03:09