Cryptography 如何从XML或本机代码中的模数/指数导入RSA公钥以与Windows CAPI';什么是密码验证签名?

Cryptography 如何从XML或本机代码中的模数/指数导入RSA公钥以与Windows CAPI';什么是密码验证签名?,cryptography,rsa,public-key,cryptoapi,mscapi,Cryptography,Rsa,Public Key,Cryptoapi,Mscapi,在C#中,我能够通过以下任一方式验证公钥的哈希值: // Import from raw modulus and exponent using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { RSAParameters rsaKeyInfo = new RSAParameters {Modulus = modulus, Exponent = exponent}; rsa.ImportParamet

在C#中,我能够通过以下任一方式验证公钥的哈希值:

// 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);
}
我需要知道的是,在给定入站RSA公钥的情况下,如何使用CAPI完成同样的任务

除了了解如何将公钥导入加密提供程序的上下文之外,我拥有验证哈希所需的大多数CAPI函数:

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

与以下部件一起使用:

与以下文件一起使用:


NET使用的XML格式与CAPI中使用的任何关键BLOB格式都不兼容。有一个
rsacyptoserviceprovider.ExportCspBlob()
方法,该方法可能有助于PUBLICKEYBLOB从.NET转换到CAPI.MSDN链接。请尝试此链接。代码更正:RSAPUBKEY*RSAPUBKEY=(RSAPUBKEY*)(keyBlob+sizeof(BLOBHEADER))从这里开始:它不应该是
blobheader.aiKeyAlg=CALG\u RSA\u SIGN
而不是
CALG\u RSA\u KEYX
,因为他想将它与
CryptVerifySignature()
一起使用?@CITBL使用CALG\u RSA\u SIGN导入的密钥只能用于验证,而使用CALG_RSA_KEYX导入的密钥可用于加密和验证。CALG_RSA_符号也会起作用,但CALG_RSA_KEYX并没有错。这还意味着代码可以用于多种目的,而且由于这是公钥,因此不应存在安全隐患。NET使用的XML格式与CAPI中使用的任何密钥BLOB格式都不兼容。有一个
rsacyptoserviceprovider.ExportCspBlob()
方法,该方法可能有助于PUBLICKEYBLOB从.NET转换到CAPI.MSDN链接。请尝试此链接。代码更正:RSAPUBKEY*RSAPUBKEY=(RSAPUBKEY*)(keyBlob+sizeof(BLOBHEADER))从这里开始:它不应该是
blobheader.aiKeyAlg=CALG\u RSA\u SIGN
而不是
CALG\u RSA\u KEYX
,因为他想将它与
CryptVerifySignature()
一起使用?@CITBL使用CALG\u RSA\u SIGN导入的密钥只能用于验证,而使用CALG_RSA_KEYX导入的密钥可用于加密和验证。CALG_RSA_符号也会起作用,但CALG_RSA_KEYX并没有错。这也意味着代码可以用于多种目的,而且由于这是公钥,因此不应该有任何安全隐患。
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);