문제

좋아, C ++의 Win32 Crypto API를 사용하여 C# (.NET 2)에서 Rijndaelmanaged 클래스와 암호화 된 문자열을 해독하려고합니다. 그러나 나는 전혀 운이 없습니다. 모든 키, IV 및 소금 경기에서, 나는 두 테스트 앱을 모두 시계를 찾았습니다. 나는 모든 것을보고 있다고 말했고 나는 공식적으로 붙어있다.

어쨌든 여기 C#이 있습니다.

            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(GetPassPhrase(), salt, 1000);
        RijndaelManaged rijndael = new RijndaelManaged();
        rijndael.BlockSize = 128;
        rijndael.KeySize = 256;
        rijndael.Mode = CipherMode.CBC;

        rijndael.Key = pdb.GetBytes(m_KeySize);
        rijndael.IV = GetIV(iv);

        ICryptoTransform encryptor = rijndael.CreateEncryptor(); 
        MemoryStream msEncrypt = new MemoryStream();
        CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
        Byte[] encryptedBytes = null;
        Byte[] toBeEncrypted = UnicodeEncoding.Unicode.GetBytes(value);

        csEncrypt.Write(toBeEncrypted, 0, toBeEncrypted.Length);
        csEncrypt.FlushFinalBlock();
        encryptedBytes = msEncrypt.ToArray();

해독하는 C ++는 다음과 같습니다.

                                    keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
                keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
                keyBlob.hdr.reserved = 0;
                keyBlob.hdr.aiKeyAlg = CALG_AES_256;
                keyBlob.cbKeySize = KEY_SIZE;
                keyBlob.rgbKeyData = &byKey[0];

                if ( CryptImportKey( hProv, (const LPBYTE) &keyBlob, sizeof(BLOBHEADER) + sizeof(DWORD) + KEY_SIZE, 0, CRYPT_EXPORTABLE, &hKey ) )
                {

                    if ( CryptSetKeyParam( hKey, KP_IV, (const BYTE *) &byIV, 0))
                    {
                        DWORD dwLen = iDestLen;
                        if ( CryptDecrypt( hKey, 0, TRUE, 0, pbyData, &dwLen))
                        {

                            if ( dwLen < (DWORD) *plOutSize)
                            {
                                memcpy_s(pbyOutput, *plOutSize, pbyData, dwLen);

                                *plOutSize = dwLen;

                                bRet = TRUE; 
                            }
                        }
                        else
                        {
                            // Log
                            DWORD dwErr = ::GetLastError();
                            int y =0;
                        }
                    }
                }

나는 cryptacquirecontext를 성공적으로 호출하고 있으며 내 C ++가 잘 실행되고 있습니다. 누구든지 내 방식으로 오류를 발견 할 수 있습니까? 그것은 나를 우울하게하기 시작했다 :(

도움이 되었습니까?

해결책

좋아, 나는 C ++에 키 블로브에 대한 struct def를 포함하지 않았으며 헤더가있는 키에 대한 연속적인 데이터 블록이 필요하다는 것이 밝혀졌지만 키 데이터에 대한 포인터가있는 MSDN 예제를 사용하고 있었다. . 잘못되었습니다!

다른 팁

CBC 체인 모드를 사용하여 일반 텍스트를 암호화하고 있음을 알 수 있습니다.

사이퍼 텍스트를 해독하기 위해 동일한 체인 모드를 사용하고 있습니까?

(죄송합니다. 코드에서 이해할 수 없습니다)

일부 코드 (선언 등)가 누락되었으므로 확인해야 할 몇 가지 사항이 있습니다.

  • 블록 크기 - 이것은 일반적으로 키 크기와 동일해야합니다. C ++ 측에 지정하지 않기 때문에 기본값 일 수도 있다고 생각합니다. C# 측면에서 256으로 설정하면 C ++에서도 명시 적으로 지정하는 것이 가장 좋습니다.
  • 패딩 - 관리 클래스는 PKCS7을 기본 패딩으로 가지고 있습니다. 생각한다 Cryptoapi 기능의 기본이지만 확실하지 않습니다.
  • 나는 getpassphrase, getiv 등이 C ++ 측에서 사용하는 것과 동일한 키를 준다고 가정합니까?
  • 암호화 된 데이터가 프로그램간에 어떻게 전달되는지는 확실하지 않습니다. 어떤 종류의 번역 오류가있을 수 있습니까? 예를 들어 Base64, URL 인코딩 등
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top