Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.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/arrays/14.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中解密加密短信(在2.2操作系统中加密)…(正在尝试在2.3操作系统中解密)_Java_Android_Encryption_Aes - Fatal编程技术网

Java 无法在Android中解密加密短信(在2.2操作系统中加密)…(正在尝试在2.3操作系统中解密)

Java 无法在Android中解密加密短信(在2.2操作系统中加密)…(正在尝试在2.3操作系统中解密),java,android,encryption,aes,Java,Android,Encryption,Aes,我能够加密短信并将其从一个模拟器(Android 2.2)发送到另一个模拟器。 在接收端,我能够成功地进行解密。但问题是,如果在一个操作系统版本(即安卓2.2)中进行加密,并在另一个操作系统版本(安卓2.3)中尝试解密,我会遇到“错误填充异常”。我检查了一下两端是否使用了相同的钥匙。 代码如下所示 public class ED { private String Key; public ED() { Key = "abc12"; //

我能够加密短信并将其从一个模拟器(Android 2.2)发送到另一个模拟器。 在接收端,我能够成功地进行解密。但问题是,如果在一个操作系统版本(即安卓2.2)中进行加密,并在另一个操作系统版本(安卓2.3)中尝试解密,我会遇到“错误填充异常”。我检查了一下两端是否使用了相同的钥匙。 代码如下所示

public class ED {


    private  String Key;

        public ED() {
            Key = "abc12";   // Assigning default key.
        }

        public ED(String key) {
            // TODO Auto-generated constructor stub
            Key = key;

        }



        public String encrypt(String toEncrypt) throws Exception {
            byte[] rawKey = getRawKey(Key.getBytes("UTF-8"));
            byte[] result = encrypt(rawKey, toEncrypt.getBytes("UTF-8"));
            return toHex(result);
        }



        public  byte[] encrypt(byte[] key, byte[] toEncodeString) throws Exception {

            SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);

            byte[] encrypted = cipher.doFinal(toEncodeString);

            return encrypted;
        }

        private  byte[] getRawKey(byte[] key) throws Exception {

            KeyGenerator kGen = KeyGenerator.getInstance("AES");
            SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
            sr.setSeed(key);
            kGen.init(128, sr);
            SecretKey sKey = kGen.generateKey();
            byte[] raw = sKey.getEncoded();
            return raw;

        } 

    /************************************* Decription *********************************************/

            public String decrypt(String encryptedString) throws Exception {

                byte[] rawKey = getRawKey(Key.getBytes("UTF-8"));
                System.out.println("Decrypted Key in bytes : "+rawKey);


                System.out.println("Key in decryption :"+rawKey);


                SecretKeySpec sKeySpec = new SecretKeySpec(rawKey, "AES");
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.DECRYPT_MODE, sKeySpec);
                byte[] decrypted = cipher.doFinal(toByte(encryptedString));
                System.out.println("Decrypted mess in bytes---------->" +decrypted);
                return new String(decrypted);
            }






            public 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 String HEX = "0123456789ABCDEF";
            private void appendHex(StringBuffer sb, byte b) {
                sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
            }

            public 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;
            }

    }
公共类ED{
私钥;
公共教育署(){
Key=“abc12”;//分配默认键。
}
公共ED(字符串键){
//TODO自动生成的构造函数存根
钥匙=钥匙;
}
公共字符串加密(字符串到加密)引发异常{
byte[]rawKey=getRawKey(Key.getBytes(“UTF-8”);
byte[]result=encrypt(rawKey,toEncrypt.getBytes(“UTF-8”);
返回到hex(结果);
}
公共字节[]加密(字节[]密钥,字节[]toEncodeString)引发异常{
SecretKeySpec sKeySpec=新SecretKeySpec(键,“AES”);
Cipher Cipher=Cipher.getInstance(“AES”);
cipher.init(cipher.ENCRYPT_模式,sKeySpec);
字节[]加密=cipher.doFinal(toEncodeString);
返回加密;
}
私有字节[]getRawKey(字节[]键)引发异常{
KeyGenerator kGen=KeyGenerator.getInstance(“AES”);
SecureRandom sr=SecureRandom.getInstance(“SHA1PRNG”);
高级固定种子(键);
kGen.init(128,sr);
SecretKey sKey=kGen.generateKey();
字节[]原始=sKey.getEncoded();
返回原材料;
} 
/*************************************描述*********************************************/
公共字符串解密(String encryptedString)引发异常{
byte[]rawKey=getRawKey(Key.getBytes(“UTF-8”);
System.out.println(“以字节为单位的解密密钥:“+rawKey”);
System.out.println(“解密中的密钥:+rawKey”);
SecretKeySpec sKeySpec=新的SecretKeySpec(rawKey,“AES”);
Cipher Cipher=Cipher.getInstance(“AES”);
cipher.init(cipher.DECRYPT_模式,sKeySpec);
byte[]decrypted=cipher.doFinal(toByte(encryptedString));
System.out.println(“以字节为单位的解密混乱------->”+解密);
返回新字符串(已解密);
}
公共字符串toHex(字节[]buf){
如果(buf==null)
返回“”;
StringBuffer结果=新的StringBuffer(2*buf.长度);
对于(int i=0;i>4)和0x0f)).append(十六进制字符(b和0x0f));
}
公共字节[]到字节(字符串hexString){
int len=hexString.length()/2;
字节[]结果=新字节[len];
对于(int i=0;i

我正在使用sendTextMessage()函数发送短信。我读到加密/解密不依赖于操作系统,但在这种情况下,这是不正确的。配置密码(在AES中)时是否遗漏了任何重要内容?请让我知道。

是设置种子()。它不做你认为它做的事情:它只是将给定种子的熵添加到底层算法中。您可能会发现,它在两种平台上都返回不同的结果。SHA1PRNG是一个伪随机函数,但是如果它已经被植入种子,它可能会返回不同的结果。

如果问题出在密钥长度上,您可以从密码派生密钥,而不是直接使用它。您可以使用散列(如SHA-1、MD5等)并将其裁剪为正确的大小(128、192或256位),或者使用
PBEKeySpec
而不是
SecretKeySpec


这样可以消除密钥长度的问题。如果填充问题出现在明文中,我建议您使用
CipherInputStream
CipherOutputStream
,这比
Cipher更便于程序员使用。doFinal

问题在于安全随机生成。它在不同的平台上给出了不同的结果。这是因为engineNextBytes()方法中SHA1PRNG_SecureRandomImpl.java的第320行(姜饼源代码)上有一个bug修复,其中

bits = seedLength << 3 + 64; 

bits=seedLength不要仅仅因为您以相同的方式为RNG设定种子,就依赖
KeyGenerator
来生成相同的密钥。如果要预共享密钥,请共享密钥,而不是种子

您还应该完全指定加密转换:“AES/ECB/pkcs5pdadding”

最后,ECB模式不适合一般使用


请参阅,以获取一个使用JCE正确执行加密的示例。

不是答案,只是一个想法:比较了输出/输入(您发送的内容和接收的内容)-比如,对其进行哈希运算并比较结果?如果您不介意性能和Java 1.5及更高版本的兼容性,我总是使用sb.append(String.format(“%02X”,b&0xFF))。我甚至不确定最后一个0xFF(使其成为可能)是否有必要。类似的问题:非常感谢Robert。这个链接解决了我的问题。安全随机密钥生成的问题。您是对的,Owlstead先生。问题在于SecureRandom()生成,setSeed()。你说“你可能会发现它在两个平台上返回的结果不同”,这是正确的。所以解决这个问题的最好方法是使用另一种方法生成密钥。对于
bits = (seedLength << 3) + 64; 
public class Crypto {

Cipher ecipher;
Cipher dcipher;

byte[] salt = { 1, 2, 4, 5, 7, 8, 3, 6 };
int iterationCount = 1979;

Crypto(String passPhase) {
    try {
        // Create the key
        KeySpec keySpec = new PBEKeySpec(passPhase.toCharArray(), salt, iterationCount);
        SecretKey key = SecretKeyFactory.getInstance("PBEWITHSHA256AND128BITAES-CBC-BC").generateSecret(keySpec);
        ecipher = Cipher.getInstance(key.getAlgorithm()); 
        dcipher = Cipher.getInstance(key.getAlgorithm());

        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

        ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
        dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

    } catch (Exception e) {
        // TODO: handle exception
        //Toast.makeText(this, "I cought ", Toast.LENGTH_LONG).show();
    }


}

public String encrypt(String str) {
    String rVal;
    try {
        byte[] utf8 = str.getBytes("UTF8");

        byte[] enc = ecipher.doFinal(utf8);

        rVal = toHex(enc);

    } catch (Exception e) {
        // TODO: handle exception
        rVal = "Exception Caught "+e.getMessage();
    }
    return rVal;
}


public String decrypt(String str) {
    String rVal;
    try {
        byte[] dec = toByte(str);
        byte[] utf8 = dcipher.doFinal(dec);

        rVal = new String(utf8, "UTF8");

    } catch(Exception e) {
        rVal = "Error in decrypting :"+e.getMessage();
    }
    return rVal;
}

private 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;
}
private 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));
}


}