0

I am a novice android programmer that needs assistance encrypting and decrypting EditText strings stored in SharedPreferences. This seems as if it should be a very common procedure and should have many tutorials covering how to accomplish this but I have not found very good information or guidance. I followed the instructions given HERE but my data shows up in clear text when checking my xml file. Any help will be greatly appreciated.

Class receives EditText string and encodes:

private SharedPreferences sp;


Intent i;
Button regBttn,rtnBttn;
EditText rName,rPwd;
String user, pass, chk;
String stat="a";
String key = "N@!an@jajpn!==";


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{


     super.onCreate(savedInstanceState);
     setContentView(R.layout.register);

    rName=(EditText)findViewById(R.id.reg_uname);
    rPwd=(EditText)findViewById(R.id.reg_pswd);
    regBttn=(Button)findViewById(R.id.reg_button);
    rtnBttn=(Button)findViewById(R.id.rtn_button); 
    regBttn.setOnClickListener(this);
    rtnBttn.setOnClickListener(this);

    sp=this.getSharedPreferences("AccessApp", MODE_WORLD_READABLE);
    chk=sp.getString("USERNAME_KEY", "");
    if(chk.length()!=0){
    sp=getSharedPreferences("AccessApp",MODE_WORLD_WRITEABLE); 

    i=new Intent(this,AccessApp.class);
    startActivity(i); 

    }     
   }

public void onClick(View arg0) {
    user=rName.getText().toString().trim();
    pass=rPwd.getText().toString().trim();

    if(arg0==regBttn){     
       if((user.length()!=0))
        {
         if((pass.length()!=0))
            {

        sp=getSharedPreferences("AccessApp",MODE_WORLD_WRITEABLE);
        Editor myEditor=sp.edit();

        try {

            byte[ ] superSecretKeyBytes = Base64.decode(user);
            byte[] key = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
            for (int i = 0; i < superSecretKeyBytes.length && i < key.length; i++) {
                key[i] = superSecretKeyBytes[i];
                myEditor.putString("USERNAME_KEY", user);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
        try {

            byte[ ] superSecretKeyBytes = Base64.decode(pass);
            byte[] key = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
            for (int i = 0; i < superSecretKeyBytes.length && i < key.length; i++) {
                key[i] = superSecretKeyBytes[i];
                myEditor.putString("PASSWORD_KEY", pass);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        myEditor.commit();
        Toast.makeText(this, "Registration is successfull",10000).show();
        i=new Intent(this,AccessApp.class);
        startActivity(i);
        }
        else
         {
          Toast.makeText(this, "Please Enter password", 10000).show();  
         }
         }
        else{
            Toast.makeText(this,"Please Enter Username",10000).show();
         }
        }

    else if(arg0==rtnBttn){
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
         builder.setTitle("Exit");
         builder.setMessage("Do you want to exit");
         builder.setCancelable(false);
         builder.setPositiveButton("Yes",new DialogInterface.OnClickListener() {

  public void onClick(DialogInterface dialog, int which) {
  // TODO Auto-generated method stub
  finish();
  }
  });
    builder.setNegativeButton("No", new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface arg0, int arg1) {
               arg0.cancel();
            }
        });
    AlertDialog alert=builder.create();
    alert.show();

    }
}
public String encrypt(String toencrypt, byte key[]) throws Exception {
    SecretKeySpec secret = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, secret);
    byte[] encryptedbytes = cipher.doFinal(toencrypt.getBytes());
    String encrypted = Base64.encodeBytes(encryptedbytes, 0);
    return encrypted;

}

}

Class used to decrypt and compare:

public class AccessApp extends Activity implements OnClickListener {
private SharedPreferences sp;
String user,pass;
Button lBttn,cBttn;
EditText uname,pword;
Intent i;

int flag=0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{ 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    lBttn=(Button)findViewById(R.id.login_button);
    cBttn=(Button)findViewById(R.id.cancel_button);
    uname=(EditText)findViewById(R.id.username);
    pword=(EditText)findViewById(R.id.password);

    lBttn.setOnClickListener(this);
    cBttn.setOnClickListener(this);
}
public void onClick(View arg0) {

    sp=this.getSharedPreferences("AccessApp", MODE_WORLD_READABLE);
    user = sp.getString("USERNAME_KEY", "");
    pass = sp.getString("PASSWORD_KEY", "");




   if(lBttn.equals(arg0)){

      if((uname.getText().toString().equals(user))&& 
        (pword.getText().toString().equals(pass)))

            {
          Toast.makeText(this, "You are Logged In", 20000).show();

               Intent intent;
               intent=new Intent(this,details.class);
               startActivity(intent);
              flag=1;
            }

        else 
           {
            Toast.makeText(this, "Wrong Username or Password",20000).show();
            flag=0;   
           }       
        } 
        else if(cBttn==arg0){
            AlertDialog.Builder builder=new AlertDialog.Builder(this);
          builder.setTitle("Exit");
         builder.setMessage("Do you want to exit");
    builder.setCancelable(false);
    builder.setPositiveButton("Yes",new DialogInterface.OnClickListener() {

 public void onClick(DialogInterface dialog, int which) {
 // TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

 finish();
 }
 });
    builder.setNegativeButton("No", new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface arg0, int arg1) {
               arg0.cancel();
            }
        });
    AlertDialog alert=builder.create();
    alert.show();

        }

    }
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
 if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {

     Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
     finish();
 }
 return super.onKeyDown(keyCode, event);
}

public static String decrypt(String encryptedText, byte[ ] key) throws Exception {
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] toDecrypt = Base64.decode(encryptedText);
    byte[] encrypted = cipher.doFinal(toDecrypt);
    return new String(encrypted);
}
}
4

1 回答 1

1

您似乎将未加密的用户名和密码保存到编辑器:

        byte[ ] superSecretKeyBytes = Base64.decode(pass);  
        byte[] key = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
        for (int i = 0; i < superSecretKeyBytes.length && i < key.length; i++) {
            key[i] = superSecretKeyBytes[i];
            myEditor.putString("PASSWORD_KEY", pass);
        }

老实说,我不明白你为什么要这么做。你实际上在做什么似乎真的没有必要,因为你将它解码成一个字节数组,创建一个固定数量的字节数组,循环通过解码的数组,并用解码的数据替换创建的固定数量数组的数据,并且然后将未更改的字符串密码添加到编辑器(顺便说一句,您这样做太多次了)。我很确定这不是你想要做的。

我相信你在那里尝试做的实际上是对其进行加密,但你从来没有解决过它,所以让我们试试这个:

首先,您的密钥应该是一个静态变量,如果它发生变化,它将不再能够适当地加密/解密。

byte[] key = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };

现在要加密密码,根据您已有的内容,根据您的密钥(在本例中:key)和您要加密的字符串(在本例中:pass)调用您的 encrypt 方法:

String encryptedPassword = encrypt(pass, key);

现在 encryptedPassword 包含基于您输入的密钥的 Base64 加密形式的密码。现在剩下要做的就是使用编辑器保存密码的加密形式,而不是像以前那样保存未加密的形式。

myEditor.putString("PASSWORD_KEY", encryptedPassword);

所以现在当您调用 myEditor.commit() 时,您将存储加密的表单。

这是第一个源文件中编辑的 onClick 方法,用于用户名和密码加密。我没有看你的解密部分,但你应该能够根据我给你的内容弄清楚:

public void onClick(View arg0) {
    user=rName.getText().toString().trim();
    pass=rPwd.getText().toString().trim();

    if(arg0==regBttn){     
       if((user.length()!=0))
        {
          if((pass.length()!=0))
        {

        sp=getSharedPreferences("AccessApp",MODE_WORLD_WRITEABLE);
        Editor myEditor=sp.edit();

        byte[] key = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };

        try {
             String encryptedUser = encrypt(user, key);  
             myEditor.putString("USERNAME_KEY", encryptedUser); 
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   
    try {
             String encryptedPass = encrypt(pass, key);  
             myEditor.putString("PASSWORD_KEY", encryptedPass); 

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    myEditor.commit();
    Toast.makeText(this, "Registration is successfull",10000).show();
    i=new Intent(this,AccessApp.class);
    startActivity(i);
    }
    else
     {
      Toast.makeText(this, "Please Enter password", 10000).show();  
     }
     }
    else{
        Toast.makeText(this,"Please Enter Username",10000).show();
     }
    }

else if(arg0==rtnBttn){
    AlertDialog.Builder builder=new AlertDialog.Builder(this);
     builder.setTitle("Exit");
     builder.setMessage("Do you want to exit");
     builder.setCancelable(false);
     builder.setPositiveButton("Yes",new DialogInterface.OnClickListener() {

  public void onClick(DialogInterface dialog, int which) {
  // TODO Auto-generated method stub
  finish();
  }
  });
    builder.setNegativeButton("No", new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface arg0, int arg1) {
                arg0.cancel();
            }
        });
    AlertDialog alert=builder.create();
    alert.show();

    }
}

希望有帮助~

于 2012-11-09T00:50:56.507 回答