Estoy realizando la autenticación activa de los pasaportes electrónicos de acuerdo con el estándar ICAO 9303 (parte11).
- Envíe un desafío al chip, el chip lo firma utilizando su clave privada (almacenada dentro del chip, no legible)
- El chip envía la firma.
- Luego verifica la firma usando la clave pública (se puede leer desde el chip)
Hay dos posibles algoritmos de firma: RSA (RSA-SHA1, RSA-PSS, RSA-SHA224, RSA-SHA256, RSA-SHA512) y ECDSA.
En la sección 6.1.2.3 de ICAO9303 parte 11 se lee sobre ECDSA: "Para ECDSA, el formato de firma simple de acuerdo con TR-03111 SE DEBE usar. Solo curvas sin comprimir Los puntos DEBEN ser utilizados. Un algoritmo hash, cuya longitud de salida es de la misma longitud o más corta que la longitud de la La clave ECDSA en uso, SE DEBE usar. "
Lo que no entiendo es cómo uso la firma ECDSA en este formato simple con OpenSSL?
En el siguiente código EVP_DigestVerifyFinal
devuelve -1. ¿Cómo puedo llevar la firma oSIG
del formato plano al formato DER?
bool doAA(std::vector<unsigned char> oRND, std::vector<unsigned char> oSIG, std::vector<unsigned char> oPKEY)
{
EVP_PKEY* m_pPubkey;
BIO* keyBio = BIO_new_mem_buf(&oPKEY[0], (int)oPKEY.size());
m_pPubkey = d2i_PUBKEY_bio(keyBio, NULL);
BIO_free(keyBio);
if (NULL == m_pPubkey)
{
std::cout << "Error Public key is NULL" << std::endl;
return false;
}
// check if ECDSA signature and then verify
int nRes = 0;
int type = EVP_PKEY_base_id(m_pPubkey);
if (type == EVP_PKEY_EC)
{
EVP_MD_CTX* ctx = EVP_MD_CTX_create();
nRes = EVP_DigestVerifyInit(ctx, NULL, EVP_sha1(), NULL, m_pPubkey);
if (1 != nRes)
{
EVP_MD_CTX_cleanup(ctx);
std::cout << "Error EVP_DigestVerifyInit" << std::endl;
return false;
}
nRes = EVP_DigestVerifyUpdate(ctx, &oRND[0], oRND.size());
if (1 != nRes)
{
EVP_MD_CTX_cleanup(ctx);
std::cout << "Error EVP_DigestVerifyUpdate" << std::endl;
return false;
}
nRes = EVP_DigestVerifyFinal(ctx, &oSIG[0], oSIG.size());
EVP_MD_CTX_cleanup(ctx);
if (nRes < 0)
{
std::cout << "Error EVP_DigestVerifyFinal failed" << std::endl;
return false;
}
else if (nRes == 0)
{
std::cout << "Error EVP_DigestVerifyFinal: Signature could not be verified" << std::endl;
return false;
}
}
else
{
std::cout << "Not a ECDSA Signature" << std::endl;
return false;
}
return nRes == 1;
}
EDITAR: este es el error que obtengo: error:0D07207B:lib(13):func(114):reason(123)