如何将.NET AES与Linux EVP加密相匹配

时间:2016-11-18 17:22:51

标签: linux encryption aes

我有一个文件需要在C#.NET应用程序中解密。在这种情况下,文件由遗留系统生成,无法修改。

以下是用于解密Linux应用程序中的文件的代码(我删除了一些与从文件加载数据有关的内容,而且这些内容并非特定于加密):

    #define BUFFER_SIZE 8192
    #define ENCRYPTION_KEY_LENGTH 16

    unsigned char OutBuf[BUFFER_SIZE];
    unsigned char InBuf[BUFFER_SIZE];

    unsigned char arucIV[ENCRYPTION_KEY_LENGTH];
    unsigned char arucKey[ENCRYPTION_KEY_LENGTH];

    istream * pIn = &std::cin;
    ostream * pOut = &std::cout;
    string sInFile, sOutFile;
    bool decrypt = false;

    int  rc, nOut, nIn;

    EVP_CIPHER_CTX * pCTX = EVP_CIPHER_CTX_new();

    pIn->read((char*)arucIV, ENCRYPTION_KEY_LENGTH);
    nIn = pIn->gcount();
    if(nIn == ENCRYPTION_KEY_LENGTH)
    {
        rc = AesKeyGen(arucIV, arucKey, ENCRYPTION_KEY_LENGTH);
        if(rc == 0)
        {
            if(EVP_DecryptInit_ex(pCTX, EVP_aes_128_ctr(), NULL, arucKey, arucIV))
            {
                while(pIn->good() && pOut->good())
                {
                    pIn->read((char*)InBuf, BUFFER_SIZE);
                    nIn = pIn->gcount();
                    if(nIn)
                    {
                        if(EVP_DecryptUpdate(pCTX, OutBuf, &nOut, InBuf, nIn))
                        {
                            pOut->write((char*)OutBuf, nOut);
                        }
                    }
                }

                if(EVP_DecryptFinal_ex(pCTX, OutBuf, &nOut))
                {
                    pOut->write((char*)OutBuf, nOut);
                }
            }
        }
        else
        {
            printf("Error Generating key.\n");
        }
    }
    else
    {
        printf("Error reading IV from input.\n");
    }

在.NET中,我尝试了这段代码,它正确地解密了前16个字节,但其余的都是垃圾:

        byte[] result = new byte[cipherText.Length];

        using (RijndaelManaged rm = new RijndaelManaged())
        {
            rm.BlockSize = 128;
            rm.Key = Key;
            rm.IV = IV;
            rm.Mode = CipherMode.CFB;
            rm.Padding = PaddingMode.Zeros;
            ICryptoTransform ctr = rm.CreateDecryptor();

            int position = 0;
            while (position + 128 < cipherText.Length)
            {
                ctr.TransformBlock(cipherText, position, 128, result, position);
                position += 128;
            }
            ctr.TransformFinalBlock(cipherText, position, cipherText.Length - position);
        }

所以问题是我在.NET中需要做些什么来匹配openssl / linux应用程序的解密方式?正在发生的linux盒子是使用openssl 1.0.1t。

我想我可能会尝试在Windows上构建linux应用程序,但是当我为windows 1.0.1t下载openssl时,include文件夹是空的,因此没有任何标头可用于构建它。

我该怎么办?

1 个答案:

答案 0 :(得分:1)

在CTR模式下,

EVP_aes_128_ctr是AES 128。由于CTR模式实际上是一种流密码,因此没有填充的概念。

.NET不会暴露点击率模式,所以这不能直接移植到.NET。如果您确实需要它在.NET中工作,那么您必须在CipherMode.ECB中使用AES(以及BlockSize = 128的PaddingMode.None)来实现https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29处的描述中的CTR。