15

C ++で使用するには、PEMでエンコードされたX.509証明書をWindowsCryptoAPIコンテキストにロードする必要があります。-----BEGIN RSA XXX KEY-----それらはとを持って いるものです-----END RSA XXX KEY-----。Pythonと.NETの例を見つけましたが、それらは、プレーンなWindowsCryptoAPIに関連付けることができない特定の関数を使用しています。

HCRYPTKEYを取得したら、暗号化/復号化する方法を理解しました。しかし、Base64 BLOBを.PEMファイルにインポートして、そこHCRYPTKEYから使用できるものを取得する方法がわかりません。

単に電話するだけではないという不思議な気持ちがありCryptDecodeObject()ます。

私を軌道に乗せることができる指針はありますか?私はすでに「試行錯誤」プログラミングをしてどこにも行かなくなって2日を失いました。

4

3 に答える 3

21

KJKHyperionは彼の答えで言った:

RSA公開鍵をPEM形式でインポートするための「魔法の」一連の呼び出しを発見しました。どうぞ:

  1. CryptStringToBinaryを使用してキーをバイナリブロブにデコードします。dwFlagsでCRYPT_STRING_BASE64HEADERを渡します
  2. CryptDecodeObjectExを使用してバイナリキーblobをCERT_PUBLIC_KEY_INFOにデコードします。dwCertEncodingTypeでX509_ASN_ENCODINGを渡し、lpszStructTypeでX509_PUBLIC_KEY_INFOを渡します
  3. PublicKeyブロブをCERT_PUBLIC_KEY_INFOからCryptDecodeObjectExを使用してRSAキーブロブにデコードします。dwCertEncodingTypeでX509_ASN_ENCODINGを渡し、lpszStructTypeでRSA_CSP_PUBLICKEYBLOBを渡します
  4. CryptImportKeyを使用してRSAキーblobをインポートします

このシーケンスは、何が起こっているのかを理解するのに本当に役立ちましたが、そのままでは機能しませんでした。2回目の呼び出しCryptDecodeObjectExでエラーが発生しました:「ASN.1の不正なタグ値が満たされました」。Microsoftのドキュメントを何度も理解しようと試みた結果、最初のデコードの出力を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;
}
于 2010-09-27T11:25:44.157 に答える
12

RSA公開鍵をPEM形式でインポートするための「魔法の」一連の呼び出しを発見しました。どうぞ:

  1. CryptStringToBinaryを使用してキーをバイナリブロブにデコードします。dwFlagsでCRYPT_STRING_BASE64HEADERを渡します
  2. CryptDecodeObjectExを使用してバイナリキーblobをCERT_PUBLIC_KEY_INFOにデコードします。dwCertEncodingTypeでX509_ASN_ENCODINGを渡し、lpszStructTypeでX509_PUBLIC_KEY_INFOを渡します
  3. PublicKeyブロブをCERT_PUBLIC_KEY_INFOからCryptDecodeObjectExを使用してRSAキーブロブにデコードします。dwCertEncodingTypeでX509_ASN_ENCODINGを渡し、lpszStructTypeでRSA_CSP_PUBLICKEYBLOBを渡します
  4. CryptImportKeyを使用してRSAキーblobをインポートします
于 2010-01-14T14:01:49.890 に答える
2

私は現在同じ困難に直面しています。ソリューションのコーディングはまだ完了していませんが、理解しているように、-----BEGINなど-----および-----ENDなど------タグを削除し、Base64をデコードする必要があります。 。

これにより、DERでエンコードされた文字列が残ります。これを解析して、モジュラスとパブリック指数を取得する必要があります。それらから、PUBLICKEYSTRUCおよびRSAPUBKEY構造を設定できます。幸運を ;-)

于 2009-08-26T11:28:48.220 に答える