read openssl_verify openssl_sign openssl_algo_sha256 leer firma archivo php c++ windows openssl rsa

openssl_verify - php openssl_sign p12



php openssl cadena firmada no verificada por Win CryptoAPI (1)

Para verificar el uso de CryptoAPI, invierta la firma y luego verifique. Esto se debe a que, en Windows, el orden de bytes es diferente de OpenSSL (que es Big Endian).

Puedes hacerlo de la siguiente manera

for(i=0, j=dwSigLen-1; i<j; ++i, --j) { char t = pbSignature[i]; pbSignature[i] = pbSignature[j]; pbSignature[j] = t; }

Después de eso, verifica la firma.

Esta pregunta puede ayudarlo ya que enfrenta un problema similar (firmado desde CryptoAPI y verifica con OpenSSL).

Estoy firmando texto usando php openssl e intentando verificarlo en la aplicación de Windows usando CryptoApi pero la validación siempre falla. Por favor, ayúdame.

Código PHP:

<?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 #1: "; echo sha1($data); if ($ok == 1) { echo "signature ok (as it should be)/n"; } elseif ($ok == 0) { echo "bad (there''s something wrong)/n"; } else { echo "ugly, error checking signature/n"; } $ok = openssl_verify(''tampered''.$data, $binary_signature, $public_key, OPENSSL_ALGO_SHA1); echo "check #2: "; if ($ok == 1) { echo "ERROR: Data has been tampered, but signature is still valid! Argh!/n"; } elseif ($ok == 0) { echo "bad signature (as it should be, since data has beent tampered)/n"; } else { echo "ugly, error checking signature/n"; } ?>

Código C ++:

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 script 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;