2016-10-25 13 views
0

OpenSSL에서 MS CryptoAPI로 마이그레이션해야합니다.이미 일치하는 Windows CryptoAPI 대칭 인코딩/디코딩 블록

OpenSSL을 사용하면 데이터의 N 바이트 (예 : 데이터 길이 = 32 바이트)가 지정되고 한 버퍼에서 다른 버퍼로 인코딩/디코딩됩니다. 모두 잘 작동합니다.

이제는 "CryptoAPI!"를 사용해야합니다. 그것은 , 작품을 좋아 그리고 지금은 데이터

DWORD d = (DWORD)psize; 
    result = CryptEncrypt(m_hAesKey, NULL, TRUE, 0, buffer, &d, (DWORD)bsize); 

그리고 내가 무엇을보고를 인코딩하려고

// Import AES key 
    if(!CryptImportKey(m_hProvider, (CONST BYTE*)&aeskey, structsize, NULL, 0, &m_hAesKey)) { 
     throw WinAESException("SetKey: Import key failed"); 
    } 

    // Set Mode 
    DWORD dwMode = CRYPT_MODE_ECB; //I can also use CRYPT_MODE_CBC with set of IV but let simple the code; 
    if(!CryptSetKeyParam(m_hAesKey, KP_MODE, (BYTE*)&dwMode, 0)) { 
     throw WinAESException("SetKey: Set ECB mode failed"); 
    } 

: 그래서 내가 좋아하는 뭔가를 쓰기? 인코딩 된 데이터 부분이 원본보다 큽니다. CryptEncrypt 함수가 어떻게 든 이미 패딩 데이터를 패딩 한 것을 알고 있습니까?

아무튼 코드 결과를 일반 데이터와 동일한 크기로 가져올 수 있습니까?

나는 정렬되지 않은 블록을 사용하지 않는, 내가 정확히 32 바이트, 내가하지 48 ...

내가 예상 크기를 테스트

DWORD d = 16; 
    result = CryptEncrypt(m_hAesKey, NULL, TRUE, 0, 0, &d, (DWORD)bsize); //need 32 

    d = 32; 
    result = CryptEncrypt(m_hAesKey, NULL, TRUE, 0, 0, &d, (DWORD)bsize); //need 48 

    d = 48; 
    result = CryptEncrypt(m_hAesKey, NULL, TRUE, 0, 0, &d, (DWORD)bsize); //need 64 

    d = 64; 
    result = CryptEncrypt(m_hAesKey, NULL, TRUE, 0, 0, &d, (DWORD)bsize); //need 80 

WTHF를 얻기 위해, 32 바이트를 암호화 할 때 내가 원하는 잘못된? 오후 8시 30 분 P.S. 암호화 된 결과를 원하는 크기로 자른 다음 해독하려고하면 반환 된 예상 오류 코드로 해독을 완료했지만 데이터가 올바르게 해독됩니다. 하지만이 해킹은 나를위한 것이 아닙니다 ...

+0

AES는 전체 블록 만 암호화하므로 데이터가 패딩됩니다. AES는 마지막으로 암호화 된 데이터 블록의 암호를 해독 할 때 패딩이 있다고 가정합니다. 즉, 암호화 할 마지막 데이터 블록이 AES 블록 크기와 동일한 크기 인 경우 패딩 블록을 추가해야합니다. 이 패딩이 추가되지 않으면 AES는 마지막 블록에 패딩이 포함되어 있는지 여부를 판단 할 방법이 없습니다. –

+0

OpenSSL 또는 LibTomCrypt를 사용할 때 AES ECB/CBC의 패딩을 끌 수 있습니다. MS cryptoAPI에서 그런 옵션이없는 것 같습니다 ... "NO_PADDING"플래그를 보지 못했습니다 : https://msdn.microsoft.com/en-us/library/windows/desktop/aa380272(v=vs.85).aspx (KP_PADDING 값 참조) –

+1

이것은 문제가 아니지만 ECB는 * 끔찍한 모드입니다. * 심지어 * 귀하의 메시지가 항상 한 블록 미만인 경우, 동일한 메시지를 두 번 보낸 사실이 누설됩니다. 나는 CAPI가 당신이 원하는 것을 지원하지 않는다고 생각합니다. 그러나 모든 것이 손실되지 않습니다 : BCryptEncrypt (CNG API)를 사용하십시오. 전체 블록 메시지의 패딩을 지원하지 않습니다. –

답변

-1

임시 해결책을 찾은 것 같습니다. 내가 암호화 할 필요가있을 때/전체 블록을 해독 - 내가 필요한 모든 기능을 거짓말하는 것입니다 - "그렇지 마지막/유일한 블록" 그래서하지 입력 :

result = CryptEncrypt(m_hAesKey, NULL, TRUE, 0, buffer, &d, (DWORD)bsize); 

하지만 :

result = CryptEncrypt(m_hAesKey, NULL, FALSE, 0, buffer, &d, (DWORD)bsize); 

이제 작동합니다. 그리고 그들은 블록의 시작 부분에서 정렬을 추가하기 위해 마지막 조각의 마지막에 패딩 데이터의 개념을 변경하지 않기를 희망합니다 ...

+0

이와 같은 수정은 발생하기를 기다리는 재앙 일뿐입니다. 문제와 해결책을 완전히 이해해야합니다. 패딩을 연구해야하며 이것이 필요한 이유는 [Padding (cryptography)] (https : //en.wikipedia.org/wiki/Padding_ (암호화)), 특히 PKCS # 7 패딩을 사용합니다. 입력 데이터가 항상 블록 크기의 배수가 아니라면 입력 데이터에 패딩을 추가해야합니다. 패딩을 지정하면 PKCS # 75가 AES의 기본 패딩입니다. – zaph

+0

필자가 맨 위에 쓸 때 - 내 데이터는 항상 정렬되어 있으며 다른 데이터는 될 수 없습니다. –

+0

패딩이 사용되면 입력 데이터가 이미 패딩 블록 전체가 추가되는 블록 크기의 정확한 배수 여도 모든 메시지에 적용되어야합니다. 마지막 바이트가 0x01이면 패딩이 있는지 어떻게 알 수 있을까요? 그래서 항상 해독 된 데이터를 살펴보십시오. 유일한 예외는 데이터가 ** 항상 ** 블록 크기의 정확한 배수이면 패딩이 필요하지 않으며 지정되지 않는다는 것입니다. – zaph