如何解密使用AES-128在Unix / Solaris上加密的C#中的文件

时间:2017-03-23 09:05:59

标签: c# unix encryption cryptography solaris

我已经提供了一个使用$ encrypt方法在Unix Solaris 10 / SunOS 5.10计算机上加密的文件。我相信这是使用aes算法完成的。

我需要在Windows机器上使用C#解密此文件。我已经提供了一个16字节的对称密钥,但我不确定如何继续。

我发现的几个代码示例提到了IV,块大小,填充,密码模式等。不幸的是,我不知道这些是什么,我对标准Unix加密方法的研究没有返回任何有用的东西。我相信我已经提供了在Unix上解密它所需的一切(虽然我没有办法测试) - 但是需要这个在C#上工作。

文件将定期提供(使用相同的密钥),因此我需要一个可以持续使用的解决方案。

非常感谢任何帮助。

感谢。

更新

感谢@Maarten(见评论)我现在有了一个有效的解决方案:

RijndaelManaged objAlgorithm = new RijndaelManaged();
//set the mode, padding and block size
objAlgorithm.Padding = PaddingMode.PKCS7;
objAlgorithm.Mode = CipherMode.CBC;
objAlgorithm.KeySize = 128;
objAlgorithm.BlockSize = 128;

byte[] key = File.ReadAllBytes(@"PATH_TO_KEY_FILE");
byte[] inputBytes = File.ReadAllBytes(@"PATH_TO_INPUT");

byte[] format = new byte[4];
byte[] iterations = new byte[4];
byte[] IV = new byte[objAlgorithm.BlockSize / 8];
byte[] salt = new byte[16];
byte[] cipherText = new byte[inputBytes.Length - format.Length - iterations.Length - IV.Length - salt.Length];

// Split the input array
Array.Copy(inputBytes, 0, format, 0, format.Length);
Array.Copy(inputBytes, format.Length, iterations, 0, iterations.Length);
Array.Copy(inputBytes, (format.Length + iterations.Length), IV, 0, IV.Length);
Array.Copy(inputBytes, (format.Length + iterations.Length + IV.Length), salt, 0, salt.Length);
Array.Copy(inputBytes, (format.Length + iterations.Length + IV.Length + salt.Length), cipherText, 0, cipherText.Length);

Byte[] outputBytes = cipherText;
string plaintext = string.Empty;

using (MemoryStream memoryStream = new MemoryStream(outputBytes))
{
    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, objAlgorithm.CreateDecryptor(key, IV), CryptoStreamMode.Read))
    {
        using (StreamReader srDecrypt = new StreamReader(cryptoStream))
        {
            try
            {
                int iReadBytes = cryptoStream.Read(outputBytes, 0, outputBytes.Length);
                //plaintext = Encoding.UTF8.GetString(outputBytes,0,outputBytes.Length);

                byte[] finalBytes = new byte[iReadBytes];
                Array.Copy(outputBytes, 0, finalBytes, 0, iReadBytes);

                File.WriteAllBytes(DirectoryPath + strOriginalFileName.Replace(".out", ".xml"), finalBytes);
            }
            catch (Exception ex)
            {
                //Handle Error
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

首先,与提供加密文件的人交谈并从中获取更多详细信息。

没有做出一些假设并尝试看看会发生什么。

您可以假设IV被添加到密文之前。您可以假设使用了CBC模式或可能是GCM模式。最初假设PKCS7填充。如果PKCS7不起作用,使用NoPadding设置解密将让您看到使用了什么填充。

请小心不要使用任何系统默认值,因为源计算机上的默认值可能与您的默认值不同。由于Unix与Microsoft不同,因此明确指定包括文本的行尾编码在内的所有内容。即使很小的细节也会干扰解密。

答案 1 :(得分:0)

你必须使用带有CBC填充和PKCS#7填充的AES,source on docs.oracle.com/..../encrypt-1.html

  

算法

     

支持的算法在-l选项中显示其最小和最大密钥大小。这些算法由加密框架提供。每个支持的算法都是PKCS#11机制的别名,这是特定算法类型中最常用和最不受限制的版本。例如,des是CKM_DES_CBC_PAD的别名,arcfour是CKM_RC4的别名。 不支持没有填充或ECB的算法变体。

这告诉你也期望CBC和PKCS#7填充AES。

此外,您必须解析由encrypt输出的密文结构(它已被定义为稳定接口,这意味着它不应在版本之间更改encrypt

  

encrypt的输出文件和decrypt的输入文件包含以下信息:

     
      
  • 输出格式版本号,网络字节顺序为4个字节。当前版本为1。

  •   
  • 密钥生成函数中使用的迭代,网络字节顺序为4个字节。

  •   
  • IV(ivlen bytes)[1]。 iv数据由等于一个块大小的随机字节生成。

  •   
  • 密钥生成中使用的盐数据(16个字节)。

  •   
  • 密文数据。

  •   

由于使用密钥文件解密不需要迭代和盐,我希望它们不存在或归零。

这应该足以在您控制的任何环境中解密。