2011-10-21 18 views
1

PHPでmcrypt_encryptを使用して暗号化された短いメッセージです - C++でMicrosoftのCryptoAPIを使用して解読しようとしています。 PHPの行は: mcrypt_encrypt(MCRYPT_RIJNDAEL_256、$ key、$ msg、MCRYPT_MODE_CBC)です。AES 256(MS CryptoAPI)を使用しているときにCryptDecryptで不正なデータエラーが発生しました

ここで、$ keyと$ msgは文字列です。 Cでは

++私は鍵を持っている、と私の復号化機能は、次のようになります。

bool decrypt(const unsigned char* input_buffer, 
       const size_t& input_size, 
       const unsigned char* key, 
       const size_t& key_size, 
       unsigned char* output_buffer, 
       DWORD* out_size) 
{ 
    Log(L"START init_crypto"); 

    bool  ret  = false; 
    HCRYPTKEY hKey  = NULL; 
    HCRYPTPROV hCryptProv = NULL; 
    DWORD  dwDataLen = 0; 

    // Attempt to acquire a handle to the crypto provider for AES 
    if(0 == CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){//PROV_RSA_AES 
    Log(L"CryptAcquireContext failed with code %ld", GetLastError()); 
     goto end; 
} 

    // key creation based on 
    // http://mirror.leaseweb.com/NetBSD/NetBSD-release-5-0/src/dist/wpa/src/crypto/crypto_cryptoapi.c 
    struct { 
    BLOBHEADER hdr; 
    DWORD len; 
    BYTE key[32]; 
    } key_blob; 

    key_blob.hdr.bType = PLAINTEXTKEYBLOB; 
    key_blob.hdr.bVersion = CUR_BLOB_VERSION; 
    key_blob.hdr.reserved = 0; 
    key_blob.hdr.aiKeyAlg = CALG_AES_256; 
    key_blob.len   = 32;//key_size; 

    memset(key_blob.key, '\0', sizeof(key_blob.key)); 

    assert(key_size <= sizeof(key_blob.key)); 
    CopyMemory(key_blob.key, key, min(key_size, sizeof(key_blob.key))); 

    if (!CryptImportKey(hCryptProv, 
        (BYTE *)&key_blob, 
        sizeof(key_blob), 
        0, 
        CRYPT_EXPORTABLE, 
        &hKey)){ 
     Log(L"Error in CryptImportKey 0x%08x \n", GetLastError()); 
     goto free_context; 
    } 
    else{ 
     //--------------------------- 
     // Set Mode 
     DWORD dwMode = CRYPT_MODE_CBC; 
     if(!CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0)){ 
      // Handle error 
      Log(L"Cannot set the cbc mode for decryption 0x%08x \n", GetLastError()); 
      goto free_key; 
     } 

     //---------------------------- 
     // Set IV 
     DWORD dwBlockLen = 0; 
     DWORD dwDataLen = sizeof(dwBlockLen); 
     if (!CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE *)&dwBlockLen, &dwDataLen, 0)){ 
      // Handle error 
      Log(_USTR("Cannot get the block length 0x%08x \n"), GetLastError()); 
      goto free_key; 
     } 
     dwBlockLen /= 8; 
     BYTE *pbTemp = NULL; 
     if (!(pbTemp = (BYTE *)LocalAlloc(LMEM_FIXED, dwBlockLen))){ 
      // Handle error 
      Log(L"Cannot allcoate the IV block 0x%08x \n", GetLastError()); 
      goto free_key; 
     } 
     memset(pbTemp, '\0', dwBlockLen); 
     if (!CryptSetKeyParam(hKey, KP_IV, pbTemp, 0)){ 
      // Handle error 
      Log(L"Cannot set the IV block 0x%08x \n", GetLastError()); 
      LocalFree(pbTemp); 
      goto free_key; 
     } 

     LocalFree(pbTemp); 
    } 

    CopyMemory(output_buffer, input_buffer, min(*out_size, input_size)); 
    *out_size = input_size; 

    if (!CryptDecrypt(hKey, NULL, TRUE, 0, output_buffer, out_size)){ 
    Log(L"CryptDecrypt failed with code %ld", GetLastError()); 
    goto free_key; 
    } 
    else{ 
    Log(L"Decryption..."); 
    ret = true; 
    } 
free_key: 
    if (hKey) 
     CryptDestroyKey(hKey); 

free_context: 
    if (hCryptProv) 
     CryptReleaseContext(hCryptProv, 0); 
end: 
    return ret; 
} 
私は一貫しCryptDecrypt()で「不正なデータ」のエラーが表示されます

...私は何かを明らかに欠落している可能性があり - もしそう、助けてください。

EDIT - 私は次のコードでCryptDecrypt(CopyMemoryのもの)の前の2行を交換し、問題の原因を単離するために: を....

strcpy((char*)output_buffer, "stuff"); 
DWORD plain_txt_len = strlen((char*)output_buffer); 
if (!CryptEncrypt(hKey, NULL, TRUE, 0, output_buffer, &plain_txt_len, *out_size)){ 
     Log(L"CryptEncrypt failed with code 0x%08x", GetLastError()); 
     goto free_key; 
} 

... とCryptDecryptがされ私は、問題がPHPからC++へのキー/メッセージ送信であると信じさせています...もしあなたが同意すれば、私がPHPで使用する文字列が次のものと同じであることを確認するヒントを与えることができますか? C++のもの(バイトレベル?)

EDIT2 - PHPでバイナリストリーム(パックを使用)を使用し、AES vs Rijndaelの回避策(?)を実装した後:http://kix.in/2008/07/22/aes-256-using-php-mcrypt/最終的にCryptDecryptにPHPメッセージの復号化を依頼しました。出力には復号化されたテキストが含まれます。なぜこれが起こる可能性があるかについてのアイデア

+0

チャネルの両端で同じパディングモードを使用していることを確認してください。 –

答えて

1

コンテキストを取得するときにCRYPT_VERIFYCONTEXTの代わりにNULLを渡すようにしてください。

関連する問題