加密类在java中工作,但在android中不工作,为什么?我还能做什么



我在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:提供者不可用:SunJCE

我从行中删除了指定的提供程序"SunJCE"。

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

我在这里找到了这个问题的解决方案

现在我在服务器端得到这个错误:

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,但我仍然有相同的错误

尝试以下代码:调用加密方法如下: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");
}

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

我遇到了几乎相同的问题,并通过切换到弹跳城堡(BC)来解决它。它存在于双方,并以完全相同的方式工作。

我使用"RSA/ECB/PKCS1Padding"作为两侧的转换。它起作用了。

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

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

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

Yo Brother,我刚刚在安卓系统上制作了一个使用加密的应用程序

看看下面这个问题

基于Java 256位AES密码的加密

看看吴(14分)的回复

只需省略import org.apache.commons.codec.binary.Hex的使用;以及它的方法(由于Hex类中使用的方法来自新版本的apacheapi,并且android已经在旧版本的apache中构建,另外,在android中,原生api优先于外部库/api)

从这个链接下载并参考org.apache.commonhttp://commons.apache.org/proper/commons-codec/

我希望它能帮助

Devel

相关内容

最新更新