2016-12-12 4 views
0

文字列を暗号化するためにキーストアを使用し、この文字列を共有設定に保存しようとしています。その後、後続のアプリ起動時に文字列を復号します。しかし、キーストアの主なポイントが不足していると思います。Androidキーストアで共有設定から文字列を復号できない

https://medium.com/@ericfu/securely-storing-secrets-in-an-android-application-501f030ae5a3#.80y72xi61

私は別の問題から

java.lang.IllegalArgumentException: bad base-64 when decrypting string

しかし、すべてのサンプルを掲載別のスレッドを使用してこのラッパーを書いた:主に、私は以下のリンクに基づいています

同じAppが実行されている間に見つけ、暗号化し、解読するコード。これは決して役に立たない。私は、私の文字列を暗号化し、どこかに保存し、後で解読する必要があります。最終的に私はこれを一度の実行を行う

private SharedPreferences mSharedPreferences;  
private void testKeystoreHelper(boolean encrypt) { 
    KeyStoreHelper keyStoreHelper; 
    initSharedPreferences(); 
    final String sharedPreferencesAlias = "mysecret"; 
    String plainText; 
    String secretString; 
    if (encrypt) { 
     plainText = "my secret string"; 
     keyStoreHelper = KeyStoreHelper.getInstance(true); 
     secretString = keyStoreHelper.encrypt(plainText); 
     Log.v(TAG, "Encrypted = " + secretString); 
     mSharedPreferences.edit().putString(sharedPreferencesAlias, secretString).apply(); 
    } else { 
     keyStoreHelper = KeyStoreHelper.getInstance(false); 
     secretString = mSharedPreferences.getString(sharedPreferencesAlias, null); 
     plainText = keyStoreHelper.decrypt(secretString); 
     Log.v(TAG, "Decrypted" + plainText); 
    } 
} 

以下のように、

@TargetApi(Build.VERSION_CODES.M) 
public KeyStoreHelper(boolean encrypt) { 
    try { 
     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
       KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); 
     if (encrypt) { 
      keyPairGenerator.initialize(
        new KeyGenParameterSpec.Builder(
          MY_KEY_NAME_INSIDE_KEYSTORE, 
          KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 
          .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 
          .build()); 
     } else { 
      keyPairGenerator.initialize(
        new KeyGenParameterSpec.Builder(
          MY_KEY_NAME_INSIDE_KEYSTORE, 
          KeyProperties.PURPOSE_DECRYPT) 
          .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 
          .build()); 
     } 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
     String provider = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? "AndroidOpenSSL" : "AndroidKeyStoreBCWorkaround"; 

     if (encrypt) { 
      PublicKey publicKey = keyPair.getPublic(); 
      mInCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider); 
      mInCipher.init(Cipher.ENCRYPT_MODE, publicKey); 
     } else { 
      PrivateKey privateKey = keyPair.getPrivate(); 
      mOutCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider); 
      mOutCipher.init(Cipher.DECRYPT_MODE, privateKey); 
     } 
    } catch (Exception e) { 
     Log.e(ERROR_TAG, Log.getStackTraceString(e)); 
    } 
} 
public static KeyStoreHelper getInstance(boolean encrypt) { 
    if (mKeyStoreHelperInstance == null) { 
     mKeyStoreHelperInstance = new KeyStoreHelper(encrypt); 
    } 
    return mKeyStoreHelperInstance; 
} 

は、その後、私はいくつかの文字列が好みに保存暗号化しようとした:だから、このラッパーは、以下のようなキーストアを初期化しようと

testKeystoreHelper(true); 

私は、アプリを終了し、これを再び実行します。

testKeystoreHelper(偽);

しかし、これは私を与える作品はありません:

E/Error: java.io.IOException: Error while finalizing cipher at 
javax.crypto.CipherInputStream.fillBuffer(CipherInputStream.java:104) 

キー名は、これらのペアは常に異なっていると同じですが、毎回アプリが起動するので:

KeyPair keyPair = keyPairGenerator.generateKeyPair(); 

私はキーを毎回初期化しておりますので。しかし、それ以外の方法でKeyPairを初期化せずに取得する方法はありますか?

私は要点を逃した、短いストーリー短い誰かが次の基本的なアルゴリズムで私をリードすることができますか?

  1. 初期ストア
  2. 文字列ECRYPTペア
  3. を取得し、好みに保存
  4. は、復号
  5. の正しいキーペアが好みから暗号化された文字列を取得する取得アプリ
  6. 初期化キーストアを終了しました
  7. メモリに解読する

これは、2つの異なるアプリの起動を使用してこれをどのように行うことができるかわかりません。私はいつも同じアプリの中で暗号化と解読のコードを見つける。

ありがとうございました!

答えて

0

質問に示されたとおり、キーストアからキーを復元し、毎回初期化しないでください。

AndroidKeyStoreをロードし、それが作成されている場合は、秘密鍵

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
keyStore.load(null); 
KeyStore.Entry entry = keyStore.getEntry(MY_KEY_NAME_INSIDE_KEYSTORE, null); 
PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); 

がキーを生成しません取得するには、このコードを使用します。

keyStore.containsAlias(MY_KEY_NAME_INSIDE_KEYSTORE); 

PublicKey publicKey = keyStore.getCertificate(MY_KEY_NAME_INSIDE_KEYSTORE).getPublicKey(); 
と公開鍵を復元して存在するかどうかをチェック
関連する問題