1

我在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");

我在这里找到了解决方案

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

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

4 回答 4

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");
}
于 2013-07-29T13:55:17.450 回答
2

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

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

我在两边都使用“RSA/ECB/PKCS1Padding”作为转换。及其工作。

于 2013-07-29T13:54:33.533 回答
2

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

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

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

于 2013-07-29T13:56:50.030 回答
1

哟兄弟,我刚刚在android上做了一个使用加密的应用程序

看看下面这个问题

Java 256 位 AES 基于密码的加密

查看 wufoo 的回复(14分)

只需省略使用 import org.apache.commons.codec.binary.Hex;及其方法(由于 Hex 类中使用的方法来自新版本的 apache api 并且 android 已经内置了旧版本的 apache,因此在 android 原生 api 中的 Plus 优先于外部库/api )

并从此链接下载并参考 org.apache.common http://commons.apache.org/proper/commons-codec/

我希望它有帮助

开发

于 2013-07-31T20:01:12.733 回答