在Android中加密并在CryptoJS中解密

时间:2017-12-10 17:44:56

标签: java android encryption cryptography aes

您好我有java代码解密使用CryptoJS库(AES)加密的密文。 现在我想编写将再次加密明文的javacode。

请找到以下代码。

 try {
        String secret = "René Über";
        String cipherText="U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hyaQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=";

        byte[] cipherData = Base64.decode(cipherText, Base64.DEFAULT);
        byte[] saltData = Arrays.copyOfRange(cipherData, 8, 16);

        MessageDigest md5 = MessageDigest.getInstance("MD5");
        final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, secret.getBytes("utf-8"), md5);
        SecretKeySpec key = new SecretKeySpec(keyAndIV[0], "AES");
        IvParameterSpec iv = new IvParameterSpec(keyAndIV[1]);

        byte[] encrypted = Arrays.copyOfRange(cipherData, 16, cipherData.length);
        Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
        aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
        byte[] decryptedData = aesCBC.doFinal(encrypted);
        String decryptedText = new String(decryptedData,"utf-8");
        System.out.println("Decrypted "+decryptedText);
//Here I get right plain text as 
//System.out: Decrypted The quick brown fox jumps over the lazy dog.


        Cipher abc=Cipher.getInstance("AES/CBC/PKCS5Padding");
        abc.init(Cipher.ENCRYPT_MODE,key,iv);
        byte[] encryptedData=abc.doFinal(decryptedData);
        String str=Base64.encodeToString(encryptedData,Base64.DEFAULT);


        System.out.println("encrypted "+str);

//Here i want the encrypted text as
// encrypted U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hy//aQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=
//but i receive 
//System.out: encrypted IZ5IDQruC+Cz0pd5krBsIM0KzbM+j4FeO8pgusm60wr6HFPCX+HJpAs5oPssshGjYjl/J5Ew+//eui



    }catch (Exception e)
    {}

当我解密代码时,我得到了正确的纯文本,但是当我再次加密纯文本时,我没有像以前那样获得加密文本。 请帮助。

GenerateKeyAndIV功能代码: -

 public static byte[][] GenerateKeyAndIV(int keyLength, int ivLength, int iterations, byte[] salt, byte[] password, MessageDigest md) {

    int digestLength = md.getDigestLength();
    int requiredLength = (keyLength + ivLength + digestLength - 1) / digestLength * digestLength;
    byte[] generatedData = new byte[requiredLength];
    int generatedLength = 0;

    try {
        md.reset();

        // Repeat process until sufficient data has been generated
        while (generatedLength < keyLength + ivLength) {

            // Digest data (last digest if available, password data, salt if available)
            if (generatedLength > 0)
                md.update(generatedData, generatedLength - digestLength, digestLength);
            md.update(password);
            if (salt != null)
                md.update(salt, 0, 8);
            md.digest(generatedData, generatedLength, digestLength);

            // additional rounds
            for (int i = 1; i < iterations; i++) {
                md.update(generatedData, generatedLength, digestLength);
                md.digest(generatedData, generatedLength, digestLength);
            }

            generatedLength += digestLength;
        }

        // Copy key and IV into separate byte arrays
        byte[][] result = new byte[2][];
        result[0] = Arrays.copyOfRange(generatedData, 0, keyLength);
        if (ivLength > 0)
            result[1] = Arrays.copyOfRange(generatedData, keyLength, keyLength + ivLength);

        return result;

    } catch (DigestException e) {
        throw new RuntimeException(e);

    } finally {
        // Clean out temporary data
        Arrays.fill(generatedData, (byte)0);
    }
}

2 个答案:

答案 0 :(得分:2)

你的密文有“盐渍__&lt; 8字节盐&gt;”在开始时,您在解密时跳过。如果要创建与OpenSSL兼容的密文,则需要在加密模式下使用相同的前缀。

当您在base64到hex解码器中查看时,您的加密代码密文似乎是正确的,例如提供here的那个。但是,因为每个字符只包含64位,并且因为字节已经移位了16个位置(不能被3整除),所以它只会使整个密文不正确,而前面只缺少16个字节。

答案 1 :(得分:0)

这里发布了我的android工作代码,我已经在服务器上使用了crypto进行解密。

  private static final String key = "aesExamplekey";
  private static final String initVector = "exampleintvec";

public static String encrypt(String value) {
    try {
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

        byte[] encrypted = cipher.doFinal(value.getBytes());

       // byte[] finalCiphertext = new byte[encrypted.length+2*16];
          return Base64.encodeToString(encrypted, Base64.NO_WRAP);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}`

服务器端代码asp.net

        public string DecryptStringAES(string cipherText)
    {
        //  var keybytes = Encoding.UTF8.GetBytes("7061737323313233");
        //  var iv = Encoding.UTF8.GetBytes("7061737323313233");
        var keybytes = Encoding.UTF8.GetBytes("aesExamplekey");
        var iv = Encoding.UTF8.GetBytes("exampleintvec");

        var encrypted = Convert.FromBase64String(cipherText);
        var decriptedFromJavascript = DecryptStringFromBytes(encrypted, keybytes, iv);
        return string.Format(decriptedFromJavascript);
    }