I'm trying to calculate message rsa signature in python 2 code using rsa
or pyopenssl
package and verify it with microsoft CryptoApi. Unfortunately, CryptVerifySignature
is always reporting error 0x80090006: Invalid signature
.
My python code:
import rsa
from OpenSSL import crypto
private_key = "-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQDFloLNqx8YZHc8D5Pk6TniJo5nwdvObNilEih2VZtTPCHooa/A\nUhz0mqh/lOKkskDNa5RCz4iTWy7wug2v+1GGlFp9jEtYq6foVu8N9DChvc8OIVV1\n4PgyFCCbCJOi5ccVUh5KBCyO8FtxHiS6a8wE3glSwsUGfzpMdrfKCYENRwIDAQAB\nAoGAJOcHZwIevJ+G5WDDbm1gsiwhTJ+YPeV2UN4jUHaMm+8PJjOMb47meYipD6ru\n6XOhRrxg5Fl+WIcfLTaSd9uoTfYIJArTPF6R2EAkcPGeil3mMSDMwqTz5eStOI/q\nRkMryHN5lCOWkm3dWXNmT/75rnqJ4dFGE1iw5dL4OJbovQECQQDyabjCqIjsTHZW\nIohqQaZAbO+wLvP4IgeUvJ31CR5Xms61FUUOe5WEs6GnSfZlsdzun+58DBEsjo7J\ncqbZxTD5AkEA0KmdPO9LMSweTSqIbH72NcIuW8cQGI2oJKNLG4Ncc7GN6ElyHJ7H\nIbRfrb2UupsLvLTDFLIrOdGWG74JGkoAPwJARGJ+tKtGtSJ835+uTAtpExOoKlOU\nj5NKADOVe+KupJgPaBYv/P3wGBd0qvS6hcW/RbHoXSYqUh+FOF8Xoqd2QQJAJeuN\nHbPHEGqaHx/ppv3ztJVTY25rqGql8fKTBa77sDLGPT6LtFPOkHt9H8/iJX9jxKl9\nAlfWry09gFEqylJEdQJAHEA0/fDR+yHxxx4w9QnfbPtn0RNHQbBzKx0K37hMu/tE\n0wxp8BFWEs5YAWWNw82ft5yOg81MH1n8iCIHzWTKrw==\n-----END RSA PRIVATE KEY-----\n"
message = "testmessage"
key = rsa.PrivateKey.load_pkcs1(private_key)
signature = rsa.sign(message, key, 'MD5')
Signature becomes aa69b87840390e6032e57f4bb... bytes, and the same signature I have via openssl dgst -md5 -sign private.pem -keyform PEM message.txt
command
My c++ code (short version):
const char kPublicVerifyKey[] =
"-----BEGIN PUBLIC KEY-----\n"
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFloLNqx8YZHc8D5Pk6TniJo5n\n"
"wdvObNilEih2VZtTPCHooa/AUhz0mqh/lOKkskDNa5RCz4iTWy7wug2v+1GGlFp9\n"
"jEtYq6foVu8N9DChvc8OIVV14PgyFCCbCJOi5ccVUh5KBCyO8FtxHiS6a8wE3glS\n"
"wsUGfzpMdrfKCYENRwIDAQAB\n"
"-----END PUBLIC KEY-----\n";
...
std::vector<unsigned char> key_buffer(public_key.size);
DWORD key_buffer_size = key_buffer.size();
if (!CryptStringToBinaryA(static_cast<const char*>(public_key.data),
public_key.size, CRYPT_STRING_BASE64HEADER,
key_buffer.data(), &key_buffer_size, NULL, NULL))
{
return false;
}
CERT_PUBLIC_KEY_INFO* key_info = nullptr;
DWORD key_info_size = 0;
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
key_buffer.data(), key_buffer_size,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &key_info, &key_info_size))
{
return false;
}
HCRYPTPROV crypt_context;
if (!CryptAcquireContext(&crypt_context, NULL, NULL,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
return false;
}
HCRYPTKEY crypt_key;
if (!::CryptImportPublicKeyInfo(crypt_context,
X509_ASN_ENCODING, key_info, &crypt_key))
{
return false;
}
HCRYPTHASH hash;
if (!::CryptCreateHash(crypt_context, CALG_MD5, 0, 0, &hash)) {
return false;
}
if (!::CryptHashData(hash,
static_cast<const BYTE*>(message.data), message.size, 0))
{
return false;
}
BOOL result = ::CryptVerifySignature(hash,
static_cast<const BYTE*>(signature.data), signature.size,
crypt_key, NULL, 0);
Why CryptVerifySignature
think that my signature is incorrect? A found related questions (php openssl signed string not getting verified by Win CryptoAPI) with advice to reverse just signature or signature and public key data bytes, but doing this with signature changes nothing and reversing public key results in error ASN1 bad tag value met. 0x8009310b
by CryptDecodeObjectEx
function.
Private key was generated with openssl genrsa -out private.pem 1024
command and public was generated with openssl rsa -in private.pem -inform PEM -outform PEM -pubout
User contributions licensed under CC BY-SA 3.0