2010-10-19 40 views
0

En C#, je suis en mesure de valider un hachage contre une clé publique dans l'une des manières suivantes:Comment puis-je importer une clé publique RSA à partir de XML ou de module/exponent en code natif pour une utilisation avec CryptVerifySignature de Windows CAPI?

// Import from raw modulus and exponent 
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { 
    RSAParameters rsaKeyInfo = new RSAParameters {Modulus = modulus, Exponent = exponent}; 
    rsa.ImportParameters(rsaKeyInfo); 
    return rsa.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA512"), signature); 
} 

// Import from XML 
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { 
    rsa.FromXmlString(xmlPublicKey); 
    return rsa.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA512"), signature); 
} 

Ce que je dois savoir comment je peux utiliser CAPI pour accomplir la même chose, étant donné un entrant RSA clé publique?

J'ai la plupart des fonctions CAPI nécessaires pour valider un hachage, sauf pour comprendre comment importer une clé publique dans le contexte du fournisseur cryptographique:

HCRYPTPROV hCryptProv; 
HCRYPTHASH hHash; 

CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0); 
CryptCreateHash(hCryptProv, CALG_SHA512, 0, 0, &hHash); 
CryptHashData(hHash, pDataToHash, lenDataToHash, 0); 
CryptVerifySignature(hHash, pSignature, sigLength, NULL, CRYPT_NOHASHOID); 
CryptDestroyHash(hHash); 
CryptReleaseContext(hCryptProv, 0); 

Merci!

Répondre

5

Utilisation CryptImportKey avec un PUBLICKEYBLOB:

HCRYPTKEY hPublicKey; 
DWORD keyBlobLength = sizeof(BLOBHEADER)+sizeof(RSAPUBKEY)+modulusLengthInBytes; 
BYTE* keyBlob = malloc(keyBlobLength); 
BLOBHEADER* blobheader = (BLOBHEADER*) keyBlob; 
blobheader.bType = PUBLICKEYBLOB; 
blobheader.bVersion = CUR_BLOB_VERSION; 
blobheader.reserved = 0; 
blobheader.aiKeyAlg = CALG_RSA_KEYX; 
RSAPUBKEY* rsapubkey = (RSAPUBKEY*) (keyBlob + sizeof(BLOBHEADER)); 
rsapubkey.magic  = 0x31415352; 
rsapubkey.bitlen = modulusLengthInBytes*8; 
rsapubkey.pubexp = 65537;   // Or whatever your public exponent is. 
BYTE* modulus = keyBlob + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY); 
memcpy(modulus, ..., modulusLengthInBytes); // NOTE: modulus must be in LSB form, 
            //  which is the opposite of what you 
            //  usually have. 
            //  .NET will give you the modulus in 
            //  MSB form, so you will have to 
            //  reverse the order of the bytes. 
CryptImportKey(hCryptProv, keyBlob, keyBlobLength, 0, 0, &hPublicKey); 
+0

Le format XML utilisé par .NET est incompatible avec * tout * des principaux formats utilisés dans BLOB CAPI. Il existe une méthode 'RSACryptoServiceProvider.ExportCspBlob()' qui pourrait faciliter la transition de .NET vers CAPI. –

+0

Le lien MSDN pour PUBLICKEYBLOB est mort. Essayez ce lien à la place. http://msdn.microsoft.com/en-us/library/windows/desktop/aa375601%28v=vs.85%29.aspx – ajs410

+0

Correction de code: 'RSAPUBKEY * rsapubkey = (RSAPUBKEY *) (keyBlob + sizeof (BLOBHEADER)); ' D'ici: http://stackoverflow.com/questions/14838123/error-importing-public-key-using-cryptoapi-cryptimportkey – lightstep