Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C加密,C++解密。解密失败的最后几个字节_C#_C++_Encryption_Cryptoapi - Fatal编程技术网

C# C加密,C++解密。解密失败的最后几个字节

C# C加密,C++解密。解密失败的最后几个字节,c#,c++,encryption,cryptoapi,C#,C++,Encryption,Cryptoapi,很抱歉,我要列出的代码太长了 我需要在我的代码的C端加密XML文件的内容,并用C++解密。我使用RC2,在C端使用RC2CuthToServIvor和CurrSt流,在C++端使用WiLyCt。加密似乎工作正常,它看起来是这样的: public static byte[] EncryptString(byte[] input, string password) { PasswordDeriveBytes pderiver = new PasswordDeriveBytes(passwor

很抱歉,我要列出的代码太长了

我需要在我的代码的C端加密XML文件的内容,并用C++解密。我使用RC2,在C端使用RC2CuthToServIvor和CurrSt流,在C++端使用WiLyCt。加密似乎工作正常,它看起来是这样的:

public static byte[] EncryptString(byte[] input, string password)
{
    PasswordDeriveBytes pderiver = new PasswordDeriveBytes(password, null);
    byte[] ivZeros = new byte[8];
    byte[] pbeKey = pderiver.CryptDeriveKey("RC2", "MD5", 128, ivZeros);

    RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider();

    byte[] IV = new byte[8];
    ICryptoTransform encryptor = RC2.CreateEncryptor(pbeKey, IV);

    MemoryStream msEncrypt = new MemoryStream();
    CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
    csEncrypt.Write(input, 0, input.Length);
    csEncrypt.FlushFinalBlock();

    return msEncrypt.ToArray();
}
我的解密代码几乎工作正常。它缺少文件的最后两个字符,而是抛出垃圾字符。我尝试过null终止解密的字符串,但没有骰子。详情如下:

char* FileReader::DecryptMyFile(char *input, char *password, int size, int originalSize) 
{
UNREFERENCED_PARAMETER(password);
HCRYPTPROV provider = NULL;
if(CryptAcquireContext(&provider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
    printf("Context acquired.");
}
else
{
    if (GetLastError() == NTE_BAD_KEYSET)
    {
        if(CryptAcquireContext(&provider, 0, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
        {
            printf("new key made.");
        }
        else
        {
            printf("Could not acquire context.");
        }
    }
    else
    {
        DWORD check = GetLastError();
        UNREFERENCED_PARAMETER(check);
        printf("Could not acquire context.");
    }
}

HCRYPTKEY key = NULL;
HCRYPTHASH hash = NULL;
if(CryptCreateHash(provider, CALG_MD5, 0, 0, &hash))
{
    printf("empty hash created.");
}

if(CryptHashData(hash, (BYTE *)password, strlen(password), 0))
{
    printf("data buffer is added to hash.");
}

HCRYPTHASH duphash = NULL;
CryptDuplicateHash(hash, 0, 0, &duphash);
BYTE *mydata = new BYTE[512];
DWORD mydatasize = 512;
CryptGetHashParam(hash, HP_HASHVAL, mydata, &mydatasize, 0);

BYTE *mydata2 = new BYTE[512]; //these duplicates were made to test my hash.
DWORD mydatasize2 = 512;  
CryptGetHashParam(duphash, HP_HASHVAL, mydata2, &mydatasize2, 0); 

if(CryptDeriveKey(provider, CALG_RC2, hash, 0, &key)) 
{
    printf("key derived."); 
}

DWORD dwKeyLength = 128;
if(CryptSetKeyParam(key, KP_EFFECTIVE_KEYLEN, reinterpret_cast<BYTE*>(&dwKeyLength), 0))
{
    printf("CryptSetKeyParam success");
}

BYTE IV[8] = {0,0,0,0,0,0,0,0};
if(CryptSetKeyParam(key, KP_IV, IV, 0))
{
    printf("CryptSetKeyParam worked");
}

DWORD dwCount = size;
BYTE *somebytes = new BYTE[dwCount + 1];

memcpy(somebytes, input, dwCount);

if(CryptDecrypt(key,0, true, 0, somebytes, &dwCount))
{
    printf("CryptDecrypt succeeded.");
}
else
{
    if(GetLastError() == NTE_BAD_DATA)
    {
        printf("NTE_BAD_DATA");
    }
    printf("CryptDecrypt failed.");
    DWORD testest = NULL;
    testest = GetLastError();
    testest = 3;
}
somebytes[originalSize] = '\0';

    return (char *)somebytes;
}

生成的xml文件应以结尾。目前,它以结尾,您不应该只执行以下操作吗

DWORD dwCount = size;
BYTE *somebytes = new BYTE[dwCount];

memcpy(somebytes, input, dwCount);
在调用cryptodecrypt之前?当CryptDecrypt已经将字节数作为其最终参数时,为什么需要添加空字符?我怀疑这就是你在originalSize-1位置敲击角色来改变输入的原因

编辑:


原版尺寸和尺寸哪个大?由于CryptDecrypt重新使用数组,因此必须使用两个数组中的较大者对其进行尺寸标注。顺便说一句,为什么你认为你需要维度中的额外一个呢?

你不应该只做以下几点吗

DWORD dwCount = size;
BYTE *somebytes = new BYTE[dwCount];

memcpy(somebytes, input, dwCount);
在调用cryptodecrypt之前?当CryptDecrypt已经将字节数作为其最终参数时,为什么需要添加空字符?我怀疑这就是你在originalSize-1位置敲击角色来改变输入的原因

编辑:


原版尺寸和尺寸哪个大?由于CryptDecrypt重新使用数组,因此必须使用两个数组中的较大者对其进行尺寸标注。顺便说一句,为什么您认为您需要维度中的额外一个?

在调用CryptDecrypt之前,这一行是您的问题:

它正在用零覆盖最后一个块中的部分加密填充,这将导致最后一个块解密为垃圾。只需删除这行代码——密文不是以nul结尾的,它几乎肯定包含大量的嵌入式nul,解密例程使用长度参数来知道有多少数据


哦,还有。。。RC2?真的吗?

在调用CryptDecrypt之前,这一行是您的问题:

它正在用零覆盖最后一个块中的部分加密填充,这将导致最后一个块解密为垃圾。只需删除这行代码——密文不是以nul结尾的,它几乎肯定包含大量的嵌入式nul,解密例程使用长度参数来知道有多少数据


哦,还有。。。RC2?真的吗?

在完成对加密流的写入后,需要刷新FileStream,然后最后刷新加密流。之后,首先关闭加密流,最后关闭文件流。如果不这样做,则可能无法写入所有原始字节(无论来自MemoryStream/FileStream),从而导致丢失字节。完成后,如果FileStream.Position不等于FileStream.Length,则FileStream.Length-FileStream.Position=缺少字节。因此,当您尝试通过序列化获取解密的数据时,如果序列化失败,您将无法获取所有数据。

在完成对加密流的写入后,您需要刷新FileStream,然后最终刷新加密流。之后,首先关闭加密流,最后关闭文件流。如果不这样做,则可能无法写入所有原始字节(无论来自MemoryStream/FileStream),从而导致丢失字节。完成后,如果FileStream.Position不等于FileStream.Length,则FileStream.Length-FileStream.Position=缺少字节。因此,当您尝试通过序列化获取解密的数据时,如果序列化失败,您将无法获取所有数据。

感谢您的回复,并为延迟回复感到抱歉。你认为这条线是一个错误的选择是正确的。它被添加到那里是因为我没有得到正确的结果。如果没有它,我会在CryptDecrypt调用后得到dwCount的更新值是多少?size和originalSize的值是什么?dwCount在返回11296后等于size,而originalSize是11290。交换这些字符可能会改变返回的数据的大小,但不会改变最后两个字符应该是垃圾的事实。感谢您的回复,很抱歉回复太晚。你认为这条线是一个错误的选择是正确的。它被添加到那里是因为我没有得到正确的结果。如果没有它,我会在CryptDecrypt调用后得到dwCount的更新值是多少?size和originalSize的值是什么?dwCount在返回11296后等于size,而originalSize是11290。交换这些字符可能会改变返回数据的大小,但不会改变最后两个字符应该是垃圾的事实。您好,您是对的,但问题仍然存在。解密不起作用
不幸的是,如果我将dwCount设置为originalSize,则不会发生这种情况。@马克:dwCount仍应设置为size,请确保使用size和originalSize中的较大者对某些字节进行尺寸标注。CryptDecrypt的最后一个参数不是数组的总体尺寸,而是加密数据占用该数组的多少字节。当CryptDecrypt返回时,它会将返回数据的大小存储在dwCount中,该值应该等于originalSize。dwCount等于返回11296后的大小,而originalSize为11290。交换这些字符可能会改变返回数据的大小,但不会改变最后两个字符应该是垃圾的事实。您好,您是对的,但问题仍然存在。不幸的是,如果我将dwCount设置为originalSize,则解密不会发生。@标记:dwCount仍应设置为size,但请确保使用size和originalSize中的较大者对某些字节进行尺寸标注。CryptDecrypt的最后一个参数不是数组的总体尺寸,而是加密数据占用该数组的多少字节。当CryptDecrypt返回时,它会将返回数据的大小存储在dwCount中,该值应该等于originalSize。dwCount等于返回11296后的大小,而originalSize为11290。交换这些字符可能会改变返回数据的大小,但不会改变最后两个字符应该是垃圾的事实。请澄清originalSize和size代表什么。当然可以。originalSize表示文件在加密之前的大小。大小代表它当前的大小。嗯,我不明白。我认为在返回CryptDecrypt时,dwCount应该保留未加密数据的大小,以便知道某些字节中有多少未加密字节。我认为这个想法是通过大小和它应该回来与originalSize。有什么我遗漏的吗?我不认为你遗漏了什么。通过尝试解决这个问题,我给了自己比我需要的多得多的东西。请澄清原始尺寸和大小代表什么。当然。originalSize表示文件在加密之前的大小。大小代表它当前的大小。嗯,我不明白。我认为在返回CryptDecrypt时,dwCount应该保留未加密数据的大小,以便知道某些字节中有多少未加密字节。我认为这个想法是通过大小和它应该回来与originalSize。有什么我遗漏的吗?我不认为你遗漏了什么。通过尝试解决这个问题,我给了自己比我需要的多得多的东西。