-->

加载X509 PEM文件到Windows的CryptoAPI(Load an X509 PEM fi

2019-06-27 22:50发布

我是新来整个加密的东西,所以我请了一些基本指针。

我需要加载.PEM(X509) “----- BEGIN RSA XXX KEY ----- ----- END RSA XXX KEY -----” 到Windows加密API方面与C ++使用(我发现Python和.NET的例子,但他们使用的具体功能我无法与普通的Windows加密API)

我知道如何加密/解密,一旦我有一个HCRYPTKEY。 但是,我只是不明白如何导入在.PEM文件(S)中的Base64 blob和获得HCRYPTKEY,我可以使用了它。

我有STANGE感觉,还有更多的比简单的调用CryptDecodeObject()。

可以把我的轨道上的指针? 我已经下跌2日子里会去做“尝试错误”编程还是一无所获。

Answer 1:

KJKHyperion他说的答案 :

我发现电话导入PEM格式的RSA公钥的“魔术”序列。 干得好:

  1. 解码密钥与CryptStringToBinary二进制斑点; 通过CRYPT_STRING_BASE64HEADER在dwFlags中
  2. 解码该二进制密钥blob与CryptDecodeObjectEx一个CERT_PUBLIC_KEY_INFO; 通过X509_ASN_ENCODING在dwCertEncodingType和X509_PUBLIC_KEY_INFO在lpszStructType
  3. 解码来自CERT_PUBLIC_KEY_INFO与CryptDecodeObjectEx一个RSA密钥blob的公钥斑点; 通过X509_ASN_ENCODING在dwCertEncodingType和lpszStructType RSA_CSP_PUBLICKEYBLOB
  4. 导入与CryptImportKey RSA密钥BLOB

该序列真正帮助我理解这是怎么回事,但它并没有为我工作原样。 第二个呼叫CryptDecodeObjectEx给了我一个错误:“遇到坏ASN.1标签值”。 在了解微软文档多次尝试之后,我终于明白了拳头解码器的输出不能再解码为ASN,并且,它实际上是准备进行导入。 有了这样的认识,我发现在以下链接了答案:

http://www.ms-news.net/f2748/problem-importing-public-key-4052577.html

下面是我自己的程序,从.PEM文件导入公钥与CryptApi方面:

int main()
{
    char           pemPubKey[2048];
    int            readLen;
    char           derPubKey[2048];
    size_t         derPubKeyLen = 2048;
    CERT_PUBLIC_KEY_INFO *publicKeyInfo;
    int            publicKeyInfoLen;
    HANDLE         hFile;
    HCRYPTPROV     hProv = 0;
    HCRYPTKEY      hKey = 0;

    /*
     * Read the public key cert from the file
     */
    hFile = CreateFileA( "c:\\pub.pem", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
    if ( hFile == INVALID_HANDLE_VALUE )
    {
        fprintf( stderr, "Failed to open file. error: %d\n", GetLastError() );
    }

    if ( !ReadFile( hFile, pemPubKey, 2048, &readLen, NULL ) )
    {
        fprintf( stderr, "Failed to read file. error: %d\n", GetLastError() );
    }

    /*
     * Convert from PEM format to DER format - removes header and footer and decodes from base64
     */
    if ( !CryptStringToBinaryA( pemPubKey, 0, CRYPT_STRING_BASE64HEADER, derPubKey, &derPubKeyLen, NULL, NULL ) )
    {
        fprintf( stderr, "CryptStringToBinary failed. Err: %d\n", GetLastError() );
    }

    /*
     * Decode from DER format to CERT_PUBLIC_KEY_INFO
     */
    if ( !CryptDecodeObjectEx( X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPubKey, derPubKeyLen, 
                               CRYPT_ENCODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLen ) )
    {
        fprintf( stderr, "CryptDecodeObjectEx 1 failed. Err: %p\n", GetLastError() );
        return -1;
    }

    /*
     * Acquire context 
     */
    if( !CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) )
    {
        {
            printf( "CryptAcquireContext failed - err=0x%x.\n", GetLastError() );
            return -1;
        }
    }

    /*
     * Import the public key using the context
     */
    if ( !CryptImportPublicKeyInfo( hProv, X509_ASN_ENCODING, publicKeyInfo, &hKey ) )
    {
        fprintf( stderr, "CryptImportPublicKeyInfo failed. error: %d\n", GetLastError() );
        return -1;
    }
    LocalFree( publicKeyInfo );

    /*
     * Now use hKey to encrypt whatever you need.
     */

    return 0;
}


Answer 2:

我发现电话导入PEM格式的RSA公钥的“魔术”序列。 干得好:

  1. 解码密钥与CryptStringToBinary二进制斑点; 通过CRYPT_STRING_BASE64HEADER在dwFlags中
  2. 解码该二进制密钥blob与CryptDecodeObjectEx一个CERT_PUBLIC_KEY_INFO; 通过X509_ASN_ENCODING在dwCertEncodingType和X509_PUBLIC_KEY_INFO在lpszStructType
  3. 解码来自CERT_PUBLIC_KEY_INFO与CryptDecodeObjectEx一个RSA密钥blob的公钥斑点; 通过X509_ASN_ENCODING在dwCertEncodingType和lpszStructType RSA_CSP_PUBLICKEYBLOB
  4. 导入与CryptImportKey RSA密钥BLOB


Answer 3:

我目前正面临着同样的困难。 我还没有完成编码解决方案,但据我所知,你需要剥去----- BEGIN等-----和----- END等------标签和解码中的Base64 。

这使得你一个DER编码字符串,你需要分析得到模数和公开指数。 从这些可以填充PUBLICKEYSTRUC和RSAPUBKEY结构。 祝好运 ;-)



文章来源: Load an X509 PEM file into Windows CryptoApi