簡體   English   中英

android中的簡單加密

[英]simple encryption in android

我參考了這篇文章的簡單加密

我正在使用edittext中的一些文本,然后使用自定義對話框從用戶獲取密鑰,然后按照文章中提到的那樣創建它,加密原始文本,解密它並將其顯示到屏幕上的Textview ..但是在運行異常后如logcat中所示在代碼中。它確實非常簡單,但我是android和java的新手所以面臨困難。可能我​​覺得我在變量傳遞中做錯了

Java代碼

package com.example.encryptiondecryption;

    import java.security.SecureRandom;

    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.spec.SecretKeySpec;
    import android.app.Activity;
    import android.app.Dialog;
    import android.content.Context;
    import android.os.Bundle;
    import android.util.Base64;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;

    public class MainActivity extends Activity implements OnClickListener {

        static final String TAG = "SymmetricAlgorithmAES";
        static final String TAG1 = "encccccccc";
        EditText getData_edt, key_edt;
        Button genkey_btn, encrypt_btn, decrypt_btn;
        static String key_str = null;
        static String getData_str = null;

        static SecretKeySpec sks = null;
        static byte[] encodedBytes = null;

        static byte[] decodedBytes = null;

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

            getData_edt = (EditText) (findViewById(R.id.am_input_edt));
            genkey_btn = (Button) (findViewById(R.id.am_key_btn));
            encrypt_btn = (Button) (findViewById(R.id.am_encrypt_btn));
            decrypt_btn = (Button) (findViewById(R.id.am_decrypt_btn));
            getData_str = getData_edt.getText().toString();

            genkey_btn.setOnClickListener(this);
            encrypt_btn.setOnClickListener(this);
            decrypt_btn.setOnClickListener(this);

        }

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            switch (v.getId()) {

            case R.id.am_key_btn:
                genKey(sks);

                break;
            case R.id.am_encrypt_btn:
                encrypt(sks);

                break;
            case R.id.am_decrypt_btn:
                decrypt();

                break;

            default:
                break;
            }

        }

        private void genKey(SecretKeySpec sks) {
            // TODO Auto-generated method stub
            Context context = this;
            final Dialog myDialog = new Dialog(context);

            myDialog.setContentView(R.layout.dialog);

            myDialog.setTitle("enter key");

            key_edt = (EditText) myDialog.findViewById(R.id.dg_key_tv);
            Button ok_btn = (Button) myDialog.findViewById(R.id.dg_ok_btn);
            Button cancel_btn = (Button) myDialog.findViewById(R.id.dg_cancel_btn);

            Log.d(TAG1, key_str);

            ok_btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub

                    key_str = key_edt.getText().toString();

                }
            });
            try {
                SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
                sr.setSeed(key_str.getBytes());

                KeyGenerator kg = KeyGenerator.getInstance("AES");
                kg.init(128, sr);
                sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");
                Log.i("encrypt", sks.toString());

            } catch (Exception e) {
                Log.e(TAG, "AES secret key spec error");
            }
            cancel_btn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    myDialog.dismiss();
                }
            });
            myDialog.show();

        }

        private void encrypt(SecretKeySpec sks) {
            // TODO Auto-generated method stub

            try {
                Cipher c = Cipher.getInstance("AES");
                c.init(Cipher.ENCRYPT_MODE, sks);
                encodedBytes = c.doFinal(getData_str.getBytes());
                String encoded = Base64
                        .encodeToString(encodedBytes, Base64.DEFAULT);
                System.out.println(" " + encoded);
            } catch (Exception e) {
                Log.e(TAG, "AES encryption error");
            }
        }

        private void decrypt() {
            // TODO Auto-generated method stub

            try {
                Cipher c = Cipher.getInstance("AES");
                c.init(Cipher.DECRYPT_MODE, sks);
                decodedBytes = c.doFinal(encodedBytes);
                System.out.println(" " + new String(decodedBytes));

            } catch (Exception e) {
                Log.e(TAG, "AES decryption error");
                TextView tvdecoded = (TextView) findViewById(R.id.am_show_tv);
                tvdecoded.setText("DECOD\n" + new String(decodedBytes) + "\n");
            }
        }
    }

XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.encryptiondecryption.MainActivity" >

    <EditText
        android:id="@+id/am_input_edt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"


        android:ems="10"
        android:inputType="textMultiLine" />

    <Button
        android:id="@+id/am_key_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/am_input_edt"
        android:layout_below="@+id/am_input_edt"
        android:text="enter your key" />

    <Button
        android:id="@+id/am_encrypt_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/am_key_btn"
        android:layout_below="@+id/am_key_btn"
        android:text="Encrypt" />

    <Button
        android:id="@+id/am_decrypt_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/am_encrypt_btn"
        android:layout_below="@+id/am_encrypt_btn"
        android:text="Decrypt" />

    <TextView
        android:id="@+id/am_show_tv"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignLeft="@+id/am_decrypt_btn"
        android:layout_below="@+id/am_decrypt_btn"
        android:layout_marginTop="15dp"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

對話框的xml布局......

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/dg_key_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" >

        <requestFocus />
    </EditText>

<Button
    android:id="@+id/dg_ok_btn"
    android:layout_width="61dp"
    android:layout_height="wrap_content"
    android:text="Ok" />

<Button
    android:id="@+id/dg_cancel_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="cancel" 
   />

Logcat錯誤

02-23 23:50:17.245: E/SymmetricAlgorithmAES(12735): AES secret key spec error
02-23 23:50:17.245: W/System.err(12735): java.lang.NullPointerException
02-23 23:50:17.265: W/System.err(12735):    at com.example.encryptiondecryption.MainActivity.genKey(MainActivity.java:99)
02-23 23:50:17.265: W/System.err(12735):    at com.example.encryptiondecryption.MainActivity.onClick(MainActivity.java:56)
02-23 23:50:17.265: W/System.err(12735):    at android.view.View.performClick(View.java:4439)
02-23 23:50:17.265: W/System.err(12735):    at android.widget.Button.performClick(Button.java:139)
02-23 23:50:17.265: W/System.err(12735):    at android.view.View$PerformClick.run(View.java:18395)
02-23 23:50:17.265: W/System.err(12735):    at android.os.Handler.handleCallback(Handler.java:725)
02-23 23:50:17.265: W/System.err(12735):    at android.os.Handler.dispatchMessage(Handler.java:92)
02-23 23:50:17.265: W/System.err(12735):    at android.os.Looper.loop(Looper.java:176)
02-23 23:50:17.265: W/System.err(12735):    at android.app.ActivityThread.main(ActivityThread.java:5317)
02-23 23:50:17.265: W/System.err(12735):    at java.lang.reflect.Method.invokeNative(Native Method)
02-23 23:50:17.265: W/System.err(12735):    at java.lang.reflect.Method.invoke(Method.java:511)
02-23 23:50:17.265: W/System.err(12735):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
02-23 23:50:17.265: W/System.err(12735):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
02-23 23:50:17.265: W/System.err(12735):    at dalvik.system.NativeStart.main(Native Method)
02-23 23:50:21.579: E/ViewRootImpl(12735): sendUserActionEvent() mView == null
02-23 23:50:23.491: E/SymmetricAlgorithmAES(12735): AES encryption error
02-23 23:50:24.932: E/SymmetricAlgorithmAES(12735): AES decryption error
02-23 23:50:24.932: W/System.err(12735): java.lang.NullPointerException
02-23 23:50:24.942: W/System.err(12735):    at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(BaseBlockCipher.java:385)
02-23 23:50:24.942: W/System.err(12735):    at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(BaseBlockCipher.java:625)
02-23 23:50:24.952: W/System.err(12735):    at javax.crypto.Cipher.init(Cipher.java:519)
02-23 23:50:24.952: W/System.err(12735):    at javax.crypto.Cipher.init(Cipher.java:479)
02-23 23:50:24.952: W/System.err(12735):    at com.example.encryptiondecryption.MainActivity.decrypt(MainActivity.java:141)
02-23 23:50:24.952: W/System.err(12735):    at com.example.encryptiondecryption.MainActivity.onClick(MainActivity.java:64)
02-23 23:50:24.952: W/System.err(12735):    at android.view.View.performClick(View.java:4439)
02-23 23:50:24.952: W/System.err(12735):    at android.widget.Button.performClick(Button.java:139)
02-23 23:50:24.952: W/System.err(12735):    at android.view.View$PerformClick.run(View.java:18395)
02-23 23:50:24.952: W/System.err(12735):    at android.os.Handler.handleCallback(Handler.java:725)
02-23 23:50:24.952: W/System.err(12735):    at android.os.Handler.dispatchMessage(Handler.java:92)
02-23 23:50:24.952: W/System.err(12735):    at android.os.Looper.loop(Looper.java:176)
02-23 23:50:24.952: W/System.err(12735):    at android.app.ActivityThread.main(ActivityThread.java:5317)
02-23 23:50:24.952: W/System.err(12735):    at java.lang.reflect.Method.invokeNative(Native Method)
02-23 23:50:24.952: W/System.err(12735):    at java.lang.reflect.Method.invoke(Method.java:511)
02-23 23:50:24.952: W/System.err(12735):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
02-23 23:50:24.952: W/System.err(12735):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
02-23 23:50:24.952: W/System.err(12735):    at dalvik.system.NativeStart.main(Native Method)
02-23 23:50:24.952: D/AndroidRuntime(12735): Shutting down VM
02-23 23:50:24.952: W/dalvikvm(12735): threadid=1: thread exiting with uncaught exception (group=0x412b3930)
02-23 23:50:24.962: E/AndroidRuntime(12735): FATAL EXCEPTION: main
02-23 23:50:24.962: E/AndroidRuntime(12735): java.lang.NullPointerException
02-23 23:50:24.962: E/AndroidRuntime(12735):    at java.lang.String.<init>(String.java:141)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at com.example.encryptiondecryption.MainActivity.decrypt(MainActivity.java:148)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at com.example.encryptiondecryption.MainActivity.onClick(MainActivity.java:64)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at android.view.View.performClick(View.java:4439)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at android.widget.Button.performClick(Button.java:139)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at android.view.View$PerformClick.run(View.java:18395)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at android.os.Handler.handleCallback(Handler.java:725)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at android.os.Handler.dispatchMessage(Handler.java:92)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at android.os.Looper.loop(Looper.java:176)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at android.app.ActivityThread.main(ActivityThread.java:5317)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at java.lang.reflect.Method.invokeNative(Native Method)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at java.lang.reflect.Method.invoke(Method.java:511)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
02-23 23:50:24.962: E/AndroidRuntime(12735):    at dalvik.system.NativeStart.main(Native Method)

我認為您的一個問題是對將對象傳遞給方法時會發生什么的誤解。 在該方法中,您可以通過調用其方法來修改參數對象,但是您無法為其分配值並期望它以任何方式影響調用代碼。 有關這方面的更多詳細信息,請閱讀: Java是“傳遞引用”還是“按值傳遞”?

這會導致您的密鑰生成方法出現問題,您可以在其中傳入sks字段並希望以下代碼更改字段值:

sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");

相反,這只會影響本地方法參數變量的值。 它對你的sks字段沒有影響。 要解決此問題,請直接使用以下內容分配給該字段:

this.sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");

然后,您可以調整方法,使其不需要參數:

private void genKey() {
  // ....
}

正如另一個答案所指出的,你的sks變量的范圍需要是整個類,而不僅僅是genkey()方法。 但是,該方法中還有另一個錯誤導致規范錯誤。 它創建一個對話框窗口並將監聽器添加到“確定”按鈕,但隨后嘗試創建密鑰(當TextView仍為空時)。 生成代碼應該是單擊偵聽器的一部分。

private void genKey() {
        // TODO Auto-generated method stub
        Context context = this;
        final Dialog myDialog = new Dialog(context);

        myDialog.setContentView(R.layout.dialog);

        myDialog.setTitle("enter key");

        key_edt = (EditText) myDialog.findViewById(R.id.dg_key_tv);
        Button ok_btn = (Button) myDialog.findViewById(R.id.dg_ok_btn);
        Button cancel_btn = (Button) myDialog.findViewById(R.id.dg_cancel_btn);

        Log.d(TAG1, key_str);

        ok_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                key_str = key_edt.getText().toString();

                // only try to create the Key Spec now we have our key string
                // first check to make sure it's not blank
                if(key_str != null && !key_str.isEmpty()){
                    try {
                        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
                        sr.setSeed(key_str.getBytes());

                        KeyGenerator kg = KeyGenerator.getInstance("AES");
                        kg.init(128, sr);
                        this.sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");
                        Log.i("encrypt", sks.toString());

                    } catch (Exception e) {
                        Log.e(TAG, "AES secret key spec error");
                    }
                }
                else{   // string is empty
                    // make some toast to alert user
                }
            }
        });

        cancel_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                myDialog.dismiss();
            }
        });
        myDialog.show();

    }

另請注意,這應該使用this.sks將Keyspec存儲為類變量。 否則,一旦clickListener結束,它將被垃圾收集。 您的加密和解密函數應使用此類變量來完成其工作,並在尚未生成密鑰時顯示吐司或其他內容。

例如,使用您的encrypt()方法:

private void encrypt() {
    if (this.sks == null){
        // make toast and tell user to generate the key
    } else {
        try {
            Cipher c = Cipher.getInstance("AES");
            // use the class key spec to encrypt
            c.init(Cipher.ENCRYPT_MODE, this.sks);
            encodedBytes = c.doFinal(getData_str.getBytes());
            String encoded = Base64
                    .encodeToString(encodedBytes, Base64.DEFAULT);
            System.out.println(" " + encoded);
        } catch (Exception e) {
            Log.e(TAG, "AES encryption error");
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM