如何使用本机代码从XML或模数/指数导入RSA公钥,以与Windows CAPI的CryptVerifySignature一起使用? [英] How can I import an RSA public key from either XML or modulus/exponent in native code for use with Windows CAPI's CryptVerifySignature?

查看:143
本文介绍了如何使用本机代码从XML或模数/指数导入RSA公钥,以与Windows CAPI的CryptVerifySignature一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,我可以通过以下两种方式验证针对公钥的哈希:

  //使用(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()){
RSAParameters rsaKeyInfo = new RSAParameters {模量=模数,指数=指数};从原始模数和指数
导入。
rsa.ImportParameters(rsaKeyInfo);
return rsa.VerifyHash(hash,CryptoConfig.MapNameToOID( SHA512),签名);
}

//使用(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())从XML
导入{
rsa.FromXmlString(xmlPublicKey);
return rsa.VerifyHash(hash,CryptoConfig.MapNameToOID( SHA512),签名);
}

我需要知道的是如何使用CAPI完成同一件事

我具有验证哈希所需的大多数CAPI函数,除了了解如何将公共密钥导入密码提供者的上下文外:

  HCRYPTPROV hCryptProv; 
HCRYPTHASH哈希;

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

谢谢!

解决方案

使用 CryptImportKey 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 = factorLengthInBytes * 8;
rsapubkey.pubexp = 65537; //或您的公开指数是多少。
BYTE *模数= keyBlob + sizeof(BLOBHEADER)+ sizeof(RSAPUBKEY);
memcpy(modulus,...,factorLengthInBytes); //注意:模数必须采用LSB形式,即
//与
通常具有的相反。
// .NET将以
// MSB形式给出模数,因此您将不得不
//反转字节顺序。
CryptImportKey(hCryptProv,keyBlob,keyBlobLength,0,0,&hPublicKey);


In C#, I am able to validate a hash against a public key in either of the following ways:

// 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);
}

What I need to know is how I can use CAPI to accomplish the same thing, given an inbound RSA public key?

I have most of the CAPI functions necessary to validate a hash, except for understanding how to import a public key into the cryptographic provider's context:

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

Thanks!

解决方案

Use CryptImportKey with a 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);

这篇关于如何使用本机代码从XML或模数/指数导入RSA公钥,以与Windows CAPI的CryptVerifySignature一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆