从Dot net到Java的AES 256解密

时间:2018-02-21 14:35:08

标签: java c# encryption

我有下面不编码并尝试将其转换为java,但机器人的结果是完全不同的,在Dot net我得到实际值但在Java中我得到的值相同的长度但是价值观不同。使用的解密技术是AES 256,我可以知道我在java代码中出错了。

Dot Net Code:

public static string AESDecryptText(string input, string key)
    {
        // Get the bytes of the string
        byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
        byte[] keyBytes = Encoding.UTF8.GetBytes(key);
        keyBytes = SHA256.Create().ComputeHash(keyBytes);

        byte[] bytesDecrypted = AESDecrypt(bytesToBeDecrypted, keyBytes);

        string result = Encoding.UTF8.GetString(bytesDecrypted);

        return result;
    }

    private static byte[] AESDecrypt(byte[] bytesToBeDecrypted, byte[] keyBytes)
    {
        byte[] decryptedBytes = null;

        // Set your salt here, change it to meet your flavor:
        // The salt bytes must be at least 8 bytes.
        byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

        using (MemoryStream ms = new MemoryStream())
        {
            using (RijndaelManaged AES = new RijndaelManaged())
            {
                AES.KeySize = 256;
                AES.BlockSize = 128;

                var key = new Rfc2898DeriveBytes(keyBytes, saltBytes, 1000);
                AES.Key = key.GetBytes(AES.KeySize / 8);
                AES.IV = key.GetBytes(AES.BlockSize / 8);

                AES.Mode = CipherMode.CBC;

                using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                    cs.Close();
                }
                decryptedBytes = ms.ToArray();
            }
        }

        return decryptedBytes;
    }

在Java代码下面:

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

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

        MessageDigest md = MessageDigest.getInstance("SHA-256" );

        md.update(KEY_IV.getBytes( StandardCharsets.UTF_8 ) );
        byte[] hashDigest = md.digest();


        String encryptedHashDigest = Base64.encodeBase64String(hashDigest);

        PBEKeySpec pbeKeySpec = new PBEKeySpec(encryptedHashDigest.toCharArray(),
                salt, 1000, 384);

        Key generatedKey = factory.generateSecret(pbeKeySpec);

        byte[] extractedKey = new byte[32];
        byte[] iv = new byte[16];


        System.arraycopy(generatedKey.getEncoded(), 0, extractedKey, 0, 32);
        System.arraycopy(generatedKey.getEncoded(), 32, iv, 0, 16);


        byte[] base64Decoded = Base64.decodeBase64(toBeDecrypted);

        Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");

        c.init(2, new SecretKeySpec(extractedKey, "AES"), new IvParameterSpec(iv));

        byte[] decryptedBytes = c.doFinal(base64Decoded);

        System.out.println("Decrypted " + new String(Base64.encodeBase64(decryptedBytes), StandardCharsets.UTF_8));

1 个答案:

答案 0 :(得分:0)

您的问题似乎在这里:

 byte[] decValue = c.doFinal(decoded);

 System.out.println("Pin "+new String(decValue, StandardCharsets.UTF_8));

你有一个字节数组:decValue填充了解密的字节。这些字节在加密之前可能是也可能不是有效的UTF-8文本。无论是什么,您都需要将这些字节转换回customerData的正确格式。如果它来自数据库,那么它可能不是UTF-8,但至少部分是二进制的。例如,数字可以作为原始二进制文件保存在数据库中。

您需要检查预期数据的精确格式,并将解密的字节数组转换为相同的格式。