2015-07-23 1 views
2

Я действительно смотрел на это сообщение: Cannot generate RSA private Key on Android, но это не сработало для меня.Как хранить RSA Private Key в приложении Android

Моя идея - зашифровать токен доступа с использованием RSA-шифрования и сохранить закрытый ключ на устройстве. Я успешно зашифровал токен, используя RSA, но я потерял, где лучше всего хранить этот ключ. Я попытался сохранить его с помощью KeyStore, однако я не знаю достаточно об этом, чтобы отлаживать, почему он не работает. Продолжайте получать ошибку: java.security.UnrecoverableKeyException: нет соответствия.

Мои ключи соответствуют, но опять же, не знаю, что случилось, поскольку я не знаю достаточно об этом. Я использовал setEntry и сохранял закрытый ключ в странных и замечательных способах, которые, я уверен, если бы это сработало, это был бы не тот же ключ, когда он был возвращен.

Каков наилучший способ хранения этого Частного ключа и где ???

Я не эксперт по безопасности, поэтому любые советы по этому поводу будут оценены, а также, если я предпочитаю использовать AES?

Мой код ниже, я только использую 1 деятельность.

package com.example.rsatest; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.security.Key; 
import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.KeyStore; 
import java.security.KeyStore.LoadStoreParameter; 
import java.security.KeyStore.PasswordProtection; 
import java.security.KeyStore.ProtectionParameter; 
import java.security.KeyStore.SecretKeyEntry; 

import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 

import android.app.Activity; 
import android.content.ActivityNotFoundException; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Build; 
import android.os.Bundle; 
import android.os.DropBoxManager.Entry; 
import android.util.Base64; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 


public class MainActivity extends Activity { 
String keyStoreFile; 
Key privateKey = null; 
boolean isUnlocked = false; 
KeyStore keyStore = null; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    keyStoreFile = this.getFilesDir() + "/bpstore.keystore"; 
    try { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
      startActivity(new Intent("android.credentials.UNLOCK")); 
      isUnlocked = true; 
     } else { 
      startActivity(new Intent("com.android.credentials.UNLOCK")); 
      isUnlocked = true; 
     } 
    } catch (ActivityNotFoundException e) { 
     Log.e("TAG", "No UNLOCK activity: " + e.getMessage(), e); 
     isUnlocked = false; 
    } 

    if(isUnlocked){ 
     privateKey = GetPrivateKey(); 

     try{ 
      char[] pw =("123").toCharArray(); 
      keyStore = createKeyStore(this,keyStoreFile, pw); 
      PasswordProtection keyPassword = new PasswordProtection("pw-secret".toCharArray()); 

      SecretKey sk = new SecretKey() { 

       @Override 
       public String getFormat() { 
        // TODO Auto-generated method stub 
        return privateKey.getFormat(); 
       } 

       @Override 
       public byte[] getEncoded() { 
        // TODO Auto-generated method stub 
        return privateKey.getEncoded(); 
       } 

       @Override 
       public String getAlgorithm() { 
        // TODO Auto-generated method stub 
        return privateKey.getAlgorithm(); 
       } 
      }; 
      System.out.println(sk.getEncoded()); 
      System.out.println(privateKey.getEncoded()); 
      KeyStore.SecretKeyEntry ent = new SecretKeyEntry(sk); 
      keyStore.setEntry("pk", ent, keyPassword); 
      keyStore.store(new FileOutputStream(keyStoreFile), pw); 

      KeyStore keyStore2; 
      keyStore2 = KeyStore.getInstance("BKS"); 
      keyStore2.load(new FileInputStream(keyStoreFile), pw); 
      KeyStore.Entry entry = keyStore2.getEntry("pk", keyPassword); 
      KeyStore.SecretKeyEntry entOut = (KeyStore.SecretKeyEntry)entry; 
     }catch(Exception ex){ 
      System.out.println("Error: " + ex.toString()); 
     } 

    } 

} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 
    if (id == R.id.action_settings) { 
     return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

private KeyStore createKeyStore(Context context, String fileName, char[] pw) throws Exception { 
    System.out.println("[DIR]:" + fileName); 
    File file = new File(fileName); 

    keyStore = KeyStore.getInstance("BKS"); 

    if (file.exists()) 
    { 
     keyStore.load(new FileInputStream(file), pw); 
    } else 
    { 
     keyStore.load(null, null); 
     keyStore.store(new FileOutputStream(fileName), pw); 
    } 

    return keyStore; 
} 

private Key GetPrivateKey(){ 
    String theTestText = "This is just a simple test!"; 

    Key publicKey = null; 

    Key privateKey = null; 
    try { 
     KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
     kpg.initialize(1024); 
     KeyPair kp = kpg.genKeyPair(); 
     publicKey = kp.getPublic(); 
     privateKey = kp.getPrivate(); 
    } catch (Exception e) { 
     Log.e("", "RSA key pair error"); 
    } 

    // Encode the original data with RSA private key 
    byte[] encodedBytes = null; 
    try { 
     Cipher c = Cipher.getInstance("RSA"); 
     c.init(Cipher.ENCRYPT_MODE, privateKey); 
     encodedBytes = c.doFinal(theTestText.getBytes()); 
    } catch (Exception e) { 
     Log.e("", "RSA encryption error"); 
    } 

    // Decode the encoded data with RSA public key 
    byte[] decodedBytes = null; 
    try { 
     Cipher c = Cipher.getInstance("RSA"); 
     c.init(Cipher.DECRYPT_MODE, publicKey); 
     decodedBytes = c.doFinal(encodedBytes); 
    } catch (Exception e) { 
     Log.e("", "RSA decryption error"); 
    } 
    return privateKey; 
} 
} 

Спасибо заранее, Уоррен

+0

Этот другой пост был довольно специфической ошибкой. У него не было правильных тегов, поэтому все пропустили его. О вашем коде; почему вы пытаетесь сохранить асимметричный ключ в качестве симметричного ключа ('SecretKey')? Это, безусловно, не сработает. Обратите внимание, что интерфейс кэширования Java в значительной степени нацелен на хранение ключей + сертификатов. Вы можете использовать другой метод хранения только для закрытых ключей RSA (например, оберните их самостоятельно, используя «Cipher»). –

+0

Спасибо, Маартен, очень ценим. Я посмотрю на его обертку с помощью шифрования и посмотрю, что я могу придумать. – EpicJoker

ответ

0

Вместо того, чтобы пытаться добавить RSA секретный ключ в хранилище ключей мы закончили с использованием AES, а и завернуть его с помощью шифра. Мы также включили ProGuard для нашего Android-проекта, чтобы усложнить декомпиляцию нашего APK.

Thank you Maarten Bodewes за ваш ответ и помощь.

That other post was a pretty specific error. It didn't have the correct tags so everybody missed it. About your code; why are you trying to store an asymmetric key as a symmetric key (SecretKey)? That will certainly not work. Note that the Java keystore interface is pretty much aimed at storing keys + certificates. You may want to use another storing method for just RSA private keys (e.g. wrap them yourself using Cipher).