zoukankan      html  css  js  c++  java
  • Load an X509 PEM file into Windows CryptoApi

    http://stackoverflow.com/questions/1231178/load-an-x509-pem-file-into-windows-cryptoapi

    I discovered the "magic" sequence of calls to import a RSA public key in PEM format. Here you go:

    1. decode the key into a binary blob with CryptStringToBinary; pass CRYPT_STRING_BASE64HEADER in dwFlags
    2. decode the binary key blob into a CERT_PUBLIC_KEY_INFO with CryptDecodeObjectEx; pass X509_ASN_ENCODING in dwCertEncodingType and X509_PUBLIC_KEY_INFO in lpszStructType
    3. decode the PublicKey blob from the CERT_PUBLIC_KEY_INFO into a RSA key blob with CryptDecodeObjectEx; pass X509_ASN_ENCODING in dwCertEncodingType and RSA_CSP_PUBLICKEYBLOB in lpszStructType
    4. import the RSA key blob with CryptImportKey

    This sequence really helped me understand what's going on, but it didn't work for me as-is. The second call to CryptDecodeObjectEx gave me an error: "ASN.1 bad tag value met". After many attempts at understanding Microsoft documentation, I finally realized that the output of the fist decode cannot be decoded as ASN again, and that it is actually ready for import. With this understanding I found the answer in the following link:

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

    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
    ", GetLastError() );
        }
    
        if ( !ReadFile( hFile, pemPubKey, 2048, &readLen, NULL ) )
        {
            fprintf( stderr, "Failed to read file. error: %d
    ", 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
    ", 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
    ", GetLastError() );
            return -1;
        }
    
        /*
         * Acquire context 
         */
        if( !CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) )
        {
            {
                printf( "CryptAcquireContext failed - err=0x%x.
    ", GetLastError() );
                return -1;
            }
        }
    
        /*
         * Import the public key using the context
         */
        if ( !CryptImportPublicKeyInfo( hProv, X509_ASN_ENCODING, publicKeyInfo, &hKey ) )
        {
            fprintf( stderr, "CryptImportPublicKeyInfo failed. error: %d
    ", GetLastError() );
            return -1;
        }
        LocalFree( publicKeyInfo );
    
        /*
         * Now use hKey to encrypt whatever you need.
         */
    
        return 0;
    }
  • 相关阅读:
    Codeforces 798C. Mike and gcd problem 模拟构造 数组gcd大于1
    Codeforces 796C. Bank Hacking
    Codeforces 792B. Counting-out Rhyme
    gym 101164 H.Pub crawl 凸包
    hdu 6053 TrickGCD 筛法
    hdu 6041 I Curse Myself 无向图找环+优先队列
    bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分
    codeforces gym 101164 K Cutting 字符串hash
    树链剖分求lca
    UESTC 1697 简单GCD问题(一) 筛法
  • 原文地址:https://www.cnblogs.com/adylee/p/3611783.html
Copyright © 2011-2022 走看看