简体   繁体   English

如何在不同活动的android studio中加密/解密文本

[英]how to encrypt/decrypt text in android studio on different activities

I tried developing an text encryption/decryption app in android studio.我尝试在 android studio 中开发一个文本加密/解密应用程序。 So here on the MainActivity.java i ran a sample code of encryption & decryption.所以在MainActivity.java上,我运行了一个加密和解密的示例代码。

MainActivity.java主活动.java

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class MainActivity extends AppCompatActivity {

Button btn,btn2;
static final String TAG = "SymmetricAlgorithmAES";
String secr="k";
String secr2="d";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //code to use my specified defined key
    byte[] key = new byte[0];
    try {
        key = (secr+secr2).getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    MessageDigest sha = null;
    try {
        sha = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    key = sha.digest(key);
    key = Arrays.copyOf(key, 16); // use only first 128 bit

    SecretKeySpec sks = new SecretKeySpec(key, "AES");

    // Original text
    String theTestText = "This is just a simple test";
    TextView tvorig = (TextView)findViewById(R.id.tvorig);
    tvorig.setText("\n[ORIGINAL]:\n" + theTestText + "\n");

    // Encode the original data with AES
    byte[] encodedBytes = null;
    try {
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.ENCRYPT_MODE, sks);
        encodedBytes = c.doFinal(theTestText.getBytes());
    } catch (Exception e) {
        Log.e(TAG, "AES encryption error");
    }
    TextView tvencoded = (TextView)findViewById(R.id.tvencoded);
    tvencoded.setText("" +
            Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");

    // Decode the encoded data with AES
    byte[] decodedBytes = null;
    try {
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, sks);
        decodedBytes = c.doFinal(encodedBytes);
    } catch (Exception e) {
        Log.e(TAG, "AES decryption error");
    }
    TextView tvdecoded = (TextView)findViewById(R.id.tvdecoded);
    tvdecoded.setText("[DECODED]:\n" + new String(decodedBytes) + "\n");

   }

The above code works properly with correct output.上面的代码可以在正确的输出下正常工作。 But when i try to modify the code and try to write encryption and decryption in different activities, but the decryption part does not work properly.但是当我尝试修改代码并尝试在不同的活动中编写加密和解密时,但解密部分无法正常工作。

Here is the code for encryption part which works properly without any error.这是加密部分的代码,它可以正常工作,没有任何错误。

Encryption.java加密.java

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class Encryption extends AppCompatActivity {

static final String TAG = "SymmetricAlgorithmAES";
String secr="k";
String secr2="d";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.encryption);
    enc_text_edt=(EditText)findViewById(R.id.enc_text_edt);
    enc_text_btn=(Button)findViewById(R.id.enc_text_btn);
    enctv=(TextView)findViewById(R.id.enctv);

    //code to use my specified defined key
    byte[] key = new byte[0];
    try {
        key = (secr+secr2).getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    MessageDigest sha = null;
    try {
        sha = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    key = sha.digest(key);
    key = Arrays.copyOf(key, 16); // use only first 128 bit

    SecretKeySpec sks = new SecretKeySpec(key, "AES");

    final SecretKeySpec finalSks = sks;
    enc_text_btn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            try {

                // Encode the original data with AES
                byte[] encodedBytes = null;
                try {
                    Cipher c = Cipher.getInstance("AES");
                    c.init(Cipher.ENCRYPT_MODE, finalSks);
                    encodedBytes = c.doFinal(enc_text_edt.getText().toString().getBytes());
                } catch (Exception e) {
                    Log.e(TAG, "AES encryption error");
                }


                enctv.setText("[ENCRYPTED]:\n" +
                        Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");


                enc_text_edt.setText("");


            } catch (Exception e) {

                e.printStackTrace();
            }

        }
    });
}
}

code of Decryption解密代码

Decryption.java解密.java

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class Decryption extends AppCompatActivity {

Button dec_text_btn;
TextView dec_edtext_view, dectv;

static final String TAG = "SymmetricAlgorithmAES";
String secr = "k";
String secr2 = "d";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.decryption);
    dec_text_btn = (Button) findViewById(R.id.dec_text_btn);
    dec_edtext_view = (EditText) findViewById(R.id.dec_edtext_view);
    dectv = (TextView) findViewById(R.id.dectv);


    //code to use my specified defined key
    byte[] key = new byte[0];
    try {
        key = (secr + secr2).getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    MessageDigest sha = null;
    try {
        sha = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    key = sha.digest(key);
    key = Arrays.copyOf(key, 16); // use only first 128 bit

    SecretKeySpec sks = new SecretKeySpec(key, "AES");


    final SecretKeySpec finalSks = sks;
    dec_text_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            try {

                // Decode the encoded data with AES

                byte[] decodedBytes = null;
                try {
                    Cipher c = Cipher.getInstance("AES");
                    c.init(Cipher.DECRYPT_MODE, finalSks);
                    decodedBytes= c.doFinal(dec_edtext_view.getText().toString().getBytes());
                    } catch (Exception e) {
                        Log.e(TAG, "AES encryption error");
                    }

                    dectv.setText("[DECRYPTED]:\n" + new String(decodedBytes) + "\n");


                } catch (Exception e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "creptography exception see log cat....", Toast.LENGTH_SHORT).show();
                }
        }
    });
}
}

Please help me with the error.请帮我解决这个错误。 While executing Decryption part it directly shows exception "creptography exception see log cat" .在执行解密部分时,它直接显示异常"creptography exception see log cat"

After reading your code I think I have found the problem, you encode to Base64 but never decode.阅读您的代码后,我想我发现了问题,您编码为 Base64 但从未解码。 In the Encryption you do the followingEncryption您执行以下操作

enctv.setText("[ENCRYPTED]:\n" +
                        Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");

and I can guess the user copies it to the decryption field but after they click the button you do我可以猜测用户将其复制到解密字段但是在他们单击按钮后

decodedBytes= c.doFinal(dec_edtext_view.getText().toString().getBytes());

instead of decoding from Base64.而不是从 Base64 解码。 I would also like to add a few notes: You're security is not safe, you barely achieved any layer of security when the keys are in plane site like this.我还想补充几点:你的安全是不安全的,当钥匙在这样的飞机站点时,你几乎没有实现任何安全层。

Note 1:注 1:

Keys should be generated randomly with a SecureRandom .应使用SecureRandom随机生成密钥。 You can easily do it by doing the following:您可以通过执行以下操作轻松完成:

byte[] key = new byte[16];
        new SecureRandom().nextBytes(key);

Note 2:笔记2:

Use an initialization vector aka IV this is useful in case the user has typed the same message.使用初始化向量 aka IV这在用户输入相同消息的情况下很有用。 For example consider the following scenario you encrypt "Hello World" and it comes out as "ABCDEFGHIJK".例如,考虑以下场景,您加密“Hello World”,结果为“ABCDEFGHIJK”。 Now you send it again and it is again "ABCDEFGHIJK".现在你再次发送它,它又是“ABCDEFGHIJK”。 With an IV it will be different everytime as long as you generate a new IV per message, you should append this IV to the message so later in decryption you can extract it.对于 IV,只要您为每条消息生成一个新的 IV,每次都会有所不同,您应该将此 IV 附加到消息中,以便稍后在解密时可以提取它。

Note 3:注 3:

When declaring a Cipher use more than AES .声明Cipher使用的不仅仅是AES There is a great article about how to increase your security and knowledge: article link有一篇关于如何提高安全性和知识的很棒的文章: 文章链接

Note 4:注 4:

If an exception occurs don't continue on like nothing happend, you should handle it correctly and not continue on code that depends on what caused the exception.如果发生异常,不要像什么都没发生一样继续,您应该正确处理它,而不是继续执行取决于导致异常的原因的代码。

Note 5:注 5:

Learn Java more in depth instead of jumping to cryptography, you're fields should be private and some final don't declare null if you might be planning to use it later, if you do check if its null.更深入地学习 Java 而不是跳到密码学,你的字段应该是私有的,如果你打算稍后使用它,如果你检查它是否为 null,那么一些 final 不要声明 null。 Don't declare "UTF-8" in get bytes, have a constant declaring a Charset such as "UTF-8" this is easily done with Charset.forName("UTF-8")不要在获取字节中声明“UTF-8”,有一个常量声明一个字符集,例如“UTF-8”,这很容易用Charset.forName("UTF-8")

I agree with everything OughtToPrevail said.我同意 OoughtToPrevail 所说的一切。

Also, you should probably get all of that out of your activity and into a helper class.此外,您可能应该从您的活动中获得所有这些并进入帮助类。 That way it will be reusable, and you can test the in and out of it (without copying and pasting) with something that would look like this:这样它将是可重用的,您可以使用如下所示的内容测试它的进出(无需复制和粘贴):

    public void myEncryptionTest(){
    String message = "This is the message to encrypt and decrypt.";
    String pass = "pass";
    String encryption = Crypto.myEncrypt(message.getBytes(), pass);
    byte[] decryption = Crypto.myDecrypt(encryption, pass);
    String decrypted = new String(decryption);
    Log.d("****DECRYPTION:  ", decrypted);
}

Where the helper class is called "Crypto" and the two static functions you're testing are "myEncrypt" and "myDecrypt."辅助类称为“Crypto”,您正在测试的两个静态函数是“myEncrypt”和“myDecrypt”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM