【问题标题】:AES256 JAVA encryption doesn't match C# encryptionAES256 JAVA 加密与 C# 加密不匹配
【发布时间】:2017-08-02 13:34:01
【问题描述】:

在与伙伴的 JAVA API 通话时,有人要求我加密一些数据,他向我发送了以下有关加密算法的详细信息:

  • 算法:AES256
  • 密钥大小:256 位
  • 加密模式:CBC(16 位块,PKCS5Padding 为 0)
  • 输出类型:Base-64
  • 密码:0xA8703827AE586460105696504327B7BB0806FEAE96BD664F89E36868FBB48E3D
  • IV:是一个字节[16],值为0

我使用了下面的代码,但我没有得到与他匹配的结果:

public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
    byte[] encryptedBytes = null;
    byte[] saltBytes = new byte[16] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

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

            var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
            aes.Key = key.GetBytes(aes.KeySize / 8);
            aes.IV = key.GetBytes(aes.BlockSize / 8);
            aes.Padding = PaddingMode.PKCS7;

            aes.Mode = CipherMode.CBC;

            using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                cs.Close();
            }
            encryptedBytes = ms.ToArray();
        }
    }

    return encryptedBytes;
}


public string EncryptText(string input, string password)
{
    byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
    byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

    passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

    byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);

    string result = Convert.ToBase64String(bytesEncrypted);

    return result;
}

所以,当我们尝试加密 你好,你好吗? 时,我得到了不同的结果,我应该得到与他相同的结果,因为他将解密我发送的数据并会处理它。给定的示例应该有这样的结果:TJTojNoVgoqnhCj4uTv1jLBiZU7r+s/0Bm234bHU+S0=

【问题讨论】:

  • 您需要提供 java 代码才能找出他们不同意的原因。
  • 客户提到this,如果你找不到足够的,请告诉我向他询问更多信息
  • 如您所见,您的代码与该代码之间存在巨大差异,尤其是在密钥和 IV 的派生方面。
  • @JamesKPolk,好的,但实际上,我无法修复它,我对这些东西并不专业,所以,如果你能指导我完成那将是很棒的。
  • 您需要询问IV - 他们的代码中使用的 IV 是什么?它是否包含在结果密文中?同样,对于 Key,正如 James 在上面的评论中指出的那样,Key 和 IV 的逻辑必须完全匹配。还要发布完整的 Java 代码,您可以尝试匹配逻辑。也看看这个SO post 以及

标签: c# encryption aes


【解决方案1】:

我做了一些测试,现在可以达到您的预期结果。

需要进行 2 项更改。

IV

IV是最简单的,正如你所说的IV = 0,所以设置IV如下:

aes.IV = new byte[16];

在 AES 中,IV is 16 bytes。上面将创建一个 16 字节的字节数组,每个值都初始化为零。

您提供的密码以“0x”开头 - 这基本上意味着这是密码字符串的十六进制表示。我使用this将此密码转换为字节数组

string password = "A8703827AE586460105696504327B7BB0806FEAE96BD664F89E36868FBB48E3D";

请注意,我从上面删除了开头的“0x”

byte[] passwordBytes = StringToByteArray(password);

上面将十六进制密码表示转换为字节数组。

在你的AES_Encrypt方法中,直接把这个byte[]赋值为Key

aes.Key = passwordBytes;

现在,我的结果是 TJTojNoVgoqnhCj4uTv1jLBiZU7r+s/0Bm234bHU+S0=,它与您的预期输出完全匹配。

【讨论】:

  • 感谢 Subbu 的帮助,但在您提到的修改后我没有得到相同的结果。修改后的新代码可以下载here。非常感谢您的支持。
  • 从你的代码中删除这一行passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
  • 哇!它现在可以正常工作,我将在下周与他们联系以确保一切正常。另一方面,非常感谢 Subbu 的帮助,我真的很感激。
猜你喜欢
  • 1970-01-01
  • 2017-08-08
  • 2021-03-19
  • 2019-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多