加密类在java中工作但在android中没有,为什么?我还可以做些什么?

时间:2013-07-29 13:37:51

标签: java android encryption

我在java中做了一个简单的加密/解密字符串类并对其进行了测试。它工作正常,现在我试图在Android设备中使用它来加密字符串,将其发送到我的服务器并在那里解密它。全部使用相同的自定义类。为什么这不起作用?它根本不受支持吗?为此目的,我还能做些什么来轻松加密/解密字符串?不接受Base64:)

package crypto;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;


public class Crypto {
    public static byte[] encrypt(String message) throws Exception
    {
        String symmetricKey = "25Ae1f1711%z1 )1";
        SecretKeySpec aesKey = new SecretKeySpec(symmetricKey.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(message.getBytes());
    }
    public static String decrypt(byte[] encryptedMessage) throws Exception
    {
        String symmetricKey = "25Ae1f1711%z1 )1";
        SecretKeySpec aesKey = new SecretKeySpec(symmetricKey.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(encryptedMessage));
    }
}

在logcat中我可以看到弹出以下异常:java.security.NoSuchProviderException:Provider not avalible:SunJCE

我从该行删除了指定的提供程序“SunJCE”。

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");

我在here

上找到了解决方法

现在我在服务器端遇到此错误:

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:317)
    at javax.crypto.Cipher.doFinal(Cipher.java:1813)
    at crypto.Crypto.decrypt(Crypto.java:20)
    at io.network.UDPServer.run(UDPServer.java:37

尝试使用BC,但我仍然有同样的错误

4 个答案:

答案 0 :(得分:4)

试试这段代码: 调用加密方法如下:encrypt_text = Encrypt(Text,"avs3qt");

Encrypt函数定义:

String Encrypt(String text, String key) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    byte[] keyBytes = new byte[16];
    byte[] b = key.getBytes("UTF-8");
    int len = b.length;
    if (len > keyBytes.length)
        len = keyBytes.length;
    System.arraycopy(b, 0, keyBytes, 0, len);
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
    IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

    byte[] results = cipher.doFinal(text.getBytes("UTF-8"));
    BASE64Decoder encoder = new BASE64Decoder();
    return encoder.encodeBytes(results);
}

调用Decrypt这样的方法:

decrypt_text = Decrypt(Text, "avs3qt");

功能定义:

String Decrypt(String text, String key) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    byte[] keyBytes = new byte[16];
    byte[] b = key.getBytes("UTF-8");
    int len = b.length;
    if (len > keyBytes.length)
        len = keyBytes.length;
    System.arraycopy(b, 0, keyBytes, 0, len);
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
    IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
    cipher.init(Cipher.DECRYPT_MODE, keySpec,ivSpec);

    BASE64Decoder decoder = new BASE64Decoder();
    byte[] results = cipher.doFinal(decoder.decode(text));
    return new String(results, "UTF-8");
}

答案 1 :(得分:2)

这取决于安全提供商。在Android和JVM中有不同的默认值,并且Android上也不存在所有Sun / Oracle算法。

我有几乎相同的问题,并通过切换到弹跳城堡(BC)解决它。它存在于两侧,并且在完全相同的情况下工作。

我正在使用“RSA / ECB / PKCS1Padding”作为双方的转换。它的工作。

答案 2 :(得分:2)

除了Oracle之外,您的代码不会在任何 Java VM上运行。原因是您请求一个名为“SunJCE”的特定加密提供程序,它是Oracle(以前称为Sun)的JCE API的参考实现。

只需更改代码即可接受任何能够处理所请求算法的提供程序:

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

答案 3 :(得分:1)

哟哥哥, 我刚刚在android上创建了一个使用加密的应用程序

看看以下问题

Java 256-bit AES Password-Based Encryption

查看wufoo(有14分的人)给出的回复

只需省略使用import org.apache.commons.codec.binary.Hex;和它的方法(由于Hex类中使用的方法来自apache api和android的新版本已经内置了旧版本的apache,在Android原生api中加上优先于外部库/ api)

并从此链接http://commons.apache.org/proper/commons-codec/

下载并引用org.apache.common

我希望它有所帮助

杰韦利