Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法解密android应用程序中的字符串_Java_Android_Encryption_Cryptography - Fatal编程技术网

Java 无法解密android应用程序中的字符串

Java 无法解密android应用程序中的字符串,java,android,encryption,cryptography,Java,Android,Encryption,Cryptography,我试图开发一个可以加密和解密值的android应用程序。因此,我遵循了这个链接 到目前为止,我能够加密文本,但无法解密它。在我的代码中,我使用了与所提供链接中提到的相同的AESHeloper类 下面是我用来加密和解密值的活动类 import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; impor

我试图开发一个可以加密和解密值的android应用程序。因此,我遵循了这个链接

到目前为止,我能够加密文本,但无法解密它。在我的代码中,我使用了与所提供链接中提到的相同的AESHeloper类

下面是我用来加密和解密值的活动类

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {


    EditText text ;
    TextView encp,decriptom;

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


        text = (EditText) findViewById(R.id.editText);
        encp = (TextView) findViewById(R.id.valueexcript);
        decriptom = (TextView) findViewById(R.id.deexcript);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.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();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    public void Ecript(View v)
    {
        String Key = "avc";

        try {
           String normalTextEnc = AHShelper.encrypt(Key, text.getText().toString());
            Toast.makeText(this,normalTextEnc,Toast.LENGTH_LONG).show();

            encp.setText(normalTextEnc);


        } catch (Exception e) {
            e.printStackTrace();
        }
      //  Toast.makeText(this,"Hello",Toast.LENGTH_LONG).show();


        String decript;
        try {
            decript = AHShelper.decrypt(Key,encp.getText().toString());
            decriptom.setText(decript);
            Toast.makeText(this,decript,Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            e.printStackTrace();
        }




    }




}
我使用的AHShelper类如下所示

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class AHShelper {
    public static String encrypt(String seed, String cleartext)
            throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] result = encrypt(rawKey, cleartext.getBytes());
        return toHex(result);
    }

    public static String decrypt(String seed, String encrypted)
            throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] enc = toByte(encrypted);
        byte[] result = decrypt(rawKey, enc);
        return new String(result);
    }

    private static byte[] getRawKey(byte[] seed) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        sr.setSeed(seed);
        kgen.init(128, sr); // 192 and 256 bits may not be available
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return raw;
    }

    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(clear);
        return encrypted;
    }

    private static byte[] decrypt(byte[] raw, byte[] encrypted)
            throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

    public static String toHex(String txt) {
        return toHex(txt.getBytes());
    }

    public static String fromHex(String hex) {
        return new String(toByte(hex));
    }

    public static byte[] toByte(String hexString) {
        int len = hexString.length() / 2;
        byte[] result = new byte[len];
        for (int i = 0; i < len; i++)
            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
                    16).byteValue();
        return result;
    }

    public static String toHex(byte[] buf) {
        if (buf == null)
            return "";
        StringBuffer result = new StringBuffer(2 * buf.length);
        for (int i = 0; i < buf.length; i++) {
            appendHex(result, buf[i]);
        }
        return result.toString();
    }

    private final static String HEX = "0123456789ABCDEF";

    private static void appendHex(StringBuffer sb, byte b) {
        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
    }

}
导入java.security.SecureRandom;
导入javax.crypto.Cipher;
导入javax.crypto.KeyGenerator;
导入javax.crypto.SecretKey;
导入javax.crypto.spec.SecretKeySpec;
公共类AHShelper{
公共静态字符串加密(字符串种子、字符串明文)
抛出异常{
byte[]rawKey=getRawKey(seed.getBytes());
byte[]result=encrypt(rawKey,cleartext.getBytes());
返回到hex(结果);
}
公共静态字符串解密(字符串种子,字符串加密)
抛出异常{
byte[]rawKey=getRawKey(seed.getBytes());
字节[]enc=toByte(加密);
字节[]结果=解密(rawKey,enc);
返回新字符串(结果);
}
私有静态字节[]getRawKey(字节[]种子)引发异常{
KeyGenerator kgen=KeyGenerator.getInstance(“AES”);
SecureRandom sr=SecureRandom.getInstance(“SHA1PRNG”);
高级种子(种子);
kgen.init(128,sr);//192和256位可能不可用
SecretKey skey=kgen.generateKey();
字节[]原始=skey.getEncoded();
返回原材料;
}
私有静态字节[]加密(字节[]原始,字节[]清除)引发异常{
SecretKeySpec skeySpec=新SecretKeySpec(原始,“AES”);
Cipher Cipher=Cipher.getInstance(“AES”);
cipher.init(cipher.ENCRYPT_模式,skeySpec);
字节[]加密=cipher.doFinal(清除);
返回加密;
}
私有静态字节[]解密(字节[]原始,字节[]加密)
抛出异常{
SecretKeySpec skeySpec=新SecretKeySpec(原始,“AES”);
Cipher Cipher=Cipher.getInstance(“AES”);
cipher.init(cipher.DECRYPT_模式,skeySpec);
字节[]解密=cipher.doFinal(加密);
返回解密;
}
公共静态字符串toHex(字符串txt){
返回到hex(txt.getBytes());
}
公共静态字符串fromHex(字符串十六进制){
返回新字符串(toByte(hex));
}
公共静态字节[]toByte(字符串hexString){
int len=hexString.length()/2;
字节[]结果=新字节[len];
对于(int i=0;i>4)和0x0f)).append(十六进制字符(b和0x0f));
}
}

基本上,此代码依赖于一个小技巧:如果在使用SHA1PRNG之前为SUN provider和Bouncy Castle provider设置种子,那么它将始终生成相同的随机字节流

但并非所有供应商都是如此;其他提供者只是简单地混合在种子中。换句话说,他们可以使用预先播种的PRNG,并在种子中混合。在这种情况下,
getRawKey
方法为加密和解密生成不同的密钥,这将导致解密失败

也可能是提供商决定使用基于SHA-1的不同算法,因为SUN/Oracle使用的算法没有得到很好的指定——至少是公开的


基本上,这个可怕的代码片段滥用SHA1PRNG作为密钥派生函数或KDF。如果输入是密码,则应使用真正的KDF,如PBKDF2;如果输入是密钥,则应使用HKDF。PBKDF2内置于Java中

应该删除该代码段。它是从Android代码片段复制的,但我再也找不到那个网站了。换言之,当它可用时,它似乎更不正常


使用SUN加密时检索数据的一个可能解决方案是在Oracle提供的JDK上解密数据。否则,您还可以复制SHA1PRNG的内部实现类的代码,并使用该代码对数据进行解密。注意,你需要记住太阳的来源是GPL'ed;如果你这样做的话,你需要遵守该许可证。对于较旧的Android版本,您可以使用该版本的源代码。我强烈建议以后删除这段可怕的代码,改用PBKDF2


如果您使用的实现返回一个完全随机的键,那么您就完全不走运了。你的数据不见了,句号。请放心,它将一直保密到时代的尽头。

我看到您已经更改了
AESHeloper
类的名称,你还改变了什么吗?@Titus没有,其他一切都是一样的,只是类名改变了。你能推荐一个我可以用来加密和解密值的循序渐进的教程吗?加密的问题是它是达到目的的一种手段。它永远不应该以加密某物为目标;保密可能是一个目标。如何做到这一点取决于手头的问题和可用资源(密钥或密码)。基本上,您首先确定用例,然后创建协议,执行威胁分析,然后实现。你基本上是让我跳过前三步。有时CBC是安全的(例如,用于文件加密),有时CBC是严重损坏的(在传输协议中未经验证的使用)。