I sign some text using php openssl and try to test it in a Windows application using CryptoApi, but the check always fails. Please help me.
PHP code:
<?php $data = "data that is to be hashed and signed."; $private_key = <<<EOD -----BEGIN RSA PRIVATE KEY----- MIIBOgIBAAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4Z RZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQJAL151ZeMKHEU2c1qdRKS9 sTxCcc2pVwoAGVzRccNX16tfmCf8FjxuM3WmLdsPxYoHrwb1LFNxiNk1MXrxjH3R 6QIhAPB7edmcjH4bhMaJBztcbNE1VRCEi/bisAwiPPMq9/2nAiEA3lyc5+f6DEIJ h1y6BWkdVULDSM+jpi1XiV/DevxuijMCIQCAEPGqHsF+4v7Jj+3HAgh9PU6otj2n Y79nJtCYmvhoHwIgNDePaS4inApN7omp7WdXyhPZhBmulnGDYvEoGJN66d0CIHra I2SvDkQ5CmrzkW5qPaE2oO7BSqAhRZxiYpZFb5CI -----END RSA PRIVATE KEY----- EOD; $public_key = <<<EOD -----BEGIN PUBLIC KEY----- MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6 zxqlVzz0wy2j4kQVUC4ZRZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQ== -----END PUBLIC KEY----- EOD; $binary_signature = ""; // At least with PHP 5.2.2 / OpenSSL 0.9.8b (Fedora 7) // there seems to be no need to call openssl_get_privatekey or similar. // Just pass the key as defined above openssl_sign($data, $binary_signature, $private_key, OPENSSL_ALGO_SHA1); // Check signature $ok = openssl_verify($data, $binary_signature, $public_key, OPENSSL_ALGO_SHA1); echo $binary_signature; echo "\n"; echo strlen($binary_signature); echo "\n"; echo strlen($public_key); $binary_signature="ÅâŸoÀÞü¸IOT6ê¿›¹ý"´Šæ¸Ûà$,&†-X÷bË`‡0¥u«CAÚNgϼ‡Êû`Sî"; echo "check
C ++ Code:
HCRYPTPROV hProv; BYTE *pbBuffer= (BYTE *)"data that is to be hashed and signed."; DWORD dwBufferLen = strlen((char *)pbBuffer)+1; HCRYPTHASH hHash; HCRYPTKEY hPubKey; BYTE *pbKeyBlob; // signature from PHP BYTE *pbSignature = (BYTE*)"BõŸûëN2¸GõÂÌ_;3µÜåJˆLôMÐh'*¡mø&·À„<ááø‡–e…ÎJ‡B¥tyƒ¥Óþ'N]Ù"; //------------------------------------------------------------------- char pemPubKey[2048] = "-----BEGIN PUBLIC KEY-----MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4ZRZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQ==-----END PUBLIC KEY-----"; //int readLen; unsigned char derPubKey[2048]; DWORD derPubKeyLen = 2048; CERT_PUBLIC_KEY_INFO *publicKeyInfo; DWORD publicKeyInfoLen; //HANDLE hFile; if ( !CryptStringToBinaryA( pemPubKey, 0, CRYPT_STRING_BASE64HEADER, derPubKey, &derPubKeyLen, NULL, NULL ) ) { fprintf( stderr, "CryptStringToBinary failed. Err: %d\n", GetLastError() ); } /* * Decode from DER format to CERT_PUBLIC_KEY_INFO */ if ( !CryptDecodeObjectEx( X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPubKey, derPubKeyLen, CRYPT_ENCODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLen ) ) { fprintf( stderr, "CryptDecodeObjectEx 1 failed. Err: %p\n", GetLastError() ); return -1; } // Acquire a cryptographic provider context handle. if(CryptAcquireContext( &hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { printf("CSP context acquired.\n"); } else { MyHandleError("Error during CryptAcquireContext."); } if ( CryptImportPublicKeyInfo( hProv, MY_ENCODING_TYPE, publicKeyInfo, &hPubKey ) ) { printf("The key has been imported.\n"); } else { MyHandleError("Public key import failed."); } if(publicKeyInfo) LocalFree( publicKeyInfo ); //------------------------------------------------------------------- // Create a new hash object. if(CryptCreateHash( hProv, CALG_SHA1, 0, 0, &hHash)) { printf("The hash object has been recreated. \n"); } else { MyHandleError("Error during CryptCreateHash."); } //------------------------------------------------------------------- // Compute the cryptographic hash of the buffer. if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { printf("The new hash has been created.\n"); } else { MyHandleError("Error during CryptHashData."); } //------------------------------------------------------------------- // Validate the digital signature. if(CryptVerifySignature( hHash, pbSignature, dwSigLen, hPubKey, NULL, 0)) { printf("The signature has been verified.\n"); } else { printf("Signature not validated!\n"); } //------------------------------------------------------------------- // Free memory to be used to store signature. /*if(pbSignature) free(pbSignature);*/ //------------------------------------------------------------------- // Destroy the hash object. if(hHash) CryptDestroyHash(hHash); //------------------------------------------------------------------- // Release the provider handle. if(hProv) CryptReleaseContext(hProv, 0); system("PAUSE"); return 0; MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2 + Xi / WnO + s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4ZRZD80IY + 4wIiX2YxKBZKGnd2TtPkcJ / ljkUCAwEAAQ == ----- END PUBLIC KEY -----"; HCRYPTPROV hProv; BYTE *pbBuffer= (BYTE *)"data that is to be hashed and signed."; DWORD dwBufferLen = strlen((char *)pbBuffer)+1; HCRYPTHASH hHash; HCRYPTKEY hPubKey; BYTE *pbKeyBlob; // signature from PHP BYTE *pbSignature = (BYTE*)"BõŸûëN2¸GõÂÌ_;3µÜåJˆLôMÐh'*¡mø&·À„<ááø‡–e…ÎJ‡B¥tyƒ¥Óþ'N]Ù"; //------------------------------------------------------------------- char pemPubKey[2048] = "-----BEGIN PUBLIC KEY-----MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4ZRZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQ==-----END PUBLIC KEY-----"; //int readLen; unsigned char derPubKey[2048]; DWORD derPubKeyLen = 2048; CERT_PUBLIC_KEY_INFO *publicKeyInfo; DWORD publicKeyInfoLen; //HANDLE hFile; if ( !CryptStringToBinaryA( pemPubKey, 0, CRYPT_STRING_BASE64HEADER, derPubKey, &derPubKeyLen, NULL, NULL ) ) { fprintf( stderr, "CryptStringToBinary failed. Err: %d\n", GetLastError() ); } /* * Decode from DER format to CERT_PUBLIC_KEY_INFO */ if ( !CryptDecodeObjectEx( X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPubKey, derPubKeyLen, CRYPT_ENCODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLen ) ) { fprintf( stderr, "CryptDecodeObjectEx 1 failed. Err: %p\n", GetLastError() ); return -1; } // Acquire a cryptographic provider context handle. if(CryptAcquireContext( &hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { printf("CSP context acquired.\n"); } else { MyHandleError("Error during CryptAcquireContext."); } if ( CryptImportPublicKeyInfo( hProv, MY_ENCODING_TYPE, publicKeyInfo, &hPubKey ) ) { printf("The key has been imported.\n"); } else { MyHandleError("Public key import failed."); } if(publicKeyInfo) LocalFree( publicKeyInfo ); //------------------------------------------------------------------- // Create a new hash object. if(CryptCreateHash( hProv, CALG_SHA1, 0, 0, &hHash)) { printf("The hash object has been recreated. \n"); } else { MyHandleError("Error during CryptCreateHash."); } //------------------------------------------------------------------- // Compute the cryptographic hash of the buffer. if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { printf("The new hash has been created.\n"); } else { MyHandleError("Error during CryptHashData."); } //------------------------------------------------------------------- // Validate the digital signature. if(CryptVerifySignature( hHash, pbSignature, dwSigLen, hPubKey, NULL, 0)) { printf("The signature has been verified.\n"); } else { printf("Signature not validated!\n"); } //------------------------------------------------------------------- // Free memory to be used to store signature. /*if(pbSignature) free(pbSignature);*/ //------------------------------------------------------------------- // Destroy the hash object. if(hHash) CryptDestroyHash(hHash); //------------------------------------------------------------------- // Release the provider handle. if(hProv) CryptReleaseContext(hProv, 0); system("PAUSE"); return 0;