2016-04-22 3 views
4

Die folgende MethodeKeyPairGeneratorSpec Austausch mit KeyGenParameterSpec.Builder Äquivalenten - Schlüsselspeichervorgang ist fehlgeschlagen

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); 
veraltet

Der Ersatz ich auf Aussehen kam wie diese

KeyPairGenerator 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()); 

Obwohl ich bin in der Lage, dies zu nutzen, um zu generieren ein Keypair-Eintrag und den Wert zu verschlüsseln, kann ich nicht entschlüsseln

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)); 
     } 

im decrypt Methode der folgende Befehl fehlschlägt:

Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); 
       output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey()); 

mit

java.security.InvalidKeyException: Keystore operation failed 

Ich denke, es mit dem KeyGenParamaterSpec.Builder zu tun hat, ähnlich falsche Bedingungen hat, dass die Verschlüsselung von Cipher-Typen sind falsche Saiten dasselbe in der Entschlüsselungsfunktion.

Aber das kann alles auf die Verwendung des neuen KeygenParameterSpec.Builder zurückverfolgt werden, wie die Verwendung der älteren veralteten Methode ermöglicht mir, zu verschlüsseln und zu entschlüsseln.

Wie zu beheben?

+0

versuchen, Androiden 18 -23 durch den Aufruf von keypairgeneratorspec.builder() und iam bekommen die Linie durch die Angabe veralteten Code? Ich habe eine if-Anweisung mit Ausrichtung auf 18-23? wenn ich versuche, keygenparameterspec.builder() iam zu verwenden, einen roten Fehler der Kompilierzeit-Störung zu erhalten? sieht aus wie ich keine Option, aber die veralteten Aufrufe zu verwenden? irgendwelche Vorschläge irgendjemand? –

Antwort

1

Es ist schwierig, 100% sicher zu sein, da Sie keine vollständige Stack-Ablaufverfolgung der Ausnahme bereitgestellt haben.

Ihr Code generiert den privaten Schlüssel so, dass er nur zum Signieren, nicht zum Entschlüsseln verwendet werden darf. Die Verschlüsselung funktioniert einwandfrei, da sie nicht den privaten Schlüssel verwendet - sie verwendet den öffentlichen Schlüssel und die öffentlichen Schlüssel von Android Keystore können ohne Einschränkungen verwendet werden. Die Entschlüsselung schlägt fehl, weil sie den privaten Schlüssel verwenden muss, aber Ihr Code hat die Verwendung des privaten Schlüssels für die Entschlüsselung nicht autorisiert.

Es sieht so aus, als wäre die sofortige Lösung die Autorisierung des privaten Schlüssels, der für die Entschlüsselung verwendet werden soll. Thia wird durch Auflisten von KeyProperties.PURPOSE_DECRYPT beim Aufrufen des KeyGenParameterSpec.Builder-Konstruktors erreicht. Wenn der Schlüssel nicht zum Signieren verwendet werden soll, entfernen Sie KeyProperties.PURPOSE_SIGN von dort und entfernen Sie setSignaturePaddings.

Sie brauchen auch den privaten Schlüssel Verwendung mit PKCS1Padding zu genehmigen: aufrufen setEncryptionPaddings (KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)

+0

die Ausnahme behandelt wird, gibt es keinen Absturz, der eine Stack-Ablaufverfolgung generiert, aber ich könnte beginnen, es manuell zu protokollieren – CQM

+0

Sie speichern mich mit den VerschlüsselnPaddings (KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1). Ich habe auch NONE-PADDING gesetzt, aber es stürzt auf Android 6. Deine Lösung perfekt. Danke vielmals. –

1

Als Alex ein Stück fehlt erwähnt ist KeyProperties.PURPOSE_DECRYPT andere ist setSignaturePaddings stattdessen, dass Sie setEncryptionPaddings Methode verwenden . Hier ist das Beispiel-Snippet.

new KeyGenParameterSpec.Builder(ALIAS, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 
      .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 
      // other options 
      .build() 

Weitere Informationen finden Sie unter documentation.

+0

danke, rette meinen Tag. – Devon

Verwandte Themen