3

Javaトラストストアに追加する必要があるMicrosoftからのSSTファイルがあります。

問題は、Microsoft が提供するすべてのツールであり、SST ファイルから証明書を Windows ストアに追加するため、SST ファイルから PEM ファイルを取得するのが困難です。certmgr.exe (certmgr.msc ではない) を実行すると、公開鍵を取得できますが、証明書は取得できません (pem または der で)。SST ファイルを使用してそれらを System.Security にロードする VB スクリプトと PowerShell の束を見ました。 Cryptography.X509Certificates.X509Certificate2Collection オブジェクトですが、PEM (または der ) 形式の証明書として出力する方法が見つかりません。

助言がありますか?

S

4

1 に答える 1

1

CAPI を使用して SST ファイルを証明書ストアとして開き、ファイル内の証明書を列挙することができます。次のコードはこれを行い、証明書の SHA1 ハッシュをファイル名として使用して、証明書を DER 形式でファイルに出力します。最初の引数は出力フォルダーです。残りの 1 つ以上の引数は、SST ファイルです。

    #include <stdio.h>
    #include <tchar.h>

    #include "windows.h"
    #include "wincrypt.h"
    #include "atlbase.h"

    #include <iostream>
    #include <sstream>
    #include <iomanip>
    #include <algorithm>

    std::string GetHexRepresentation(const unsigned char * Bytes, size_t Length)
    {
        std::ostringstream os;
        os.fill('0');
        os<<std::hex;
        for(const unsigned char * ptr=Bytes;ptr<Bytes+Length;ptr++)
            os<<std::setw(2)<<(unsigned int)*ptr;
        std::string retval = os.str();
        std::transform(retval.begin(), retval.end(),retval.begin(), ::toupper);
        return retval;
    }

    BOOL WriteToFileWithHashAsFilename(PCCERT_CONTEXT pPrevCertContext, TCHAR* outputDir)
    {
    #undef RETURN
    #define RETURN(rv) \
    { \
         if( hHash ) CryptDestroyHash(hHash); \
         if( hProv ) CryptReleaseContext(hProv, 0); \
        return rv; \
    } 

         HCRYPTPROV hProv = 0;
         HCRYPTHASH hHash = 0;

         BYTE byteFinalHash[20];
         DWORD dwFinalHashSize = 20;

         if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
         {
             std::cout << "CryptAcquireContext failed: " << GetLastError() << std::endl;
             RETURN(FALSE);
         }

         if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
         {
             std::cout << "CryptCreateHash failed: " << GetLastError() << std::endl;
             RETURN(FALSE);
         }

         if (!CryptHashData(hHash, pPrevCertContext->pbCertEncoded, pPrevCertContext->cbCertEncoded, 0))
         {
             std::cout << "CryptHashData failed: " << GetLastError() << std::endl;
             RETURN(FALSE);
         }

         if (!CryptGetHashParam(hHash, HP_HASHVAL, byteFinalHash, &dwFinalHashSize, 0))
         {
             std::cout << "CryptGetHashParam failed: " << GetLastError() << std::endl;
             RETURN(FALSE);
         }

         std::string strHash = GetHexRepresentation(byteFinalHash, dwFinalHashSize);
         std::wostringstream filename;
         filename << outputDir << strHash.c_str() << ".der" <<std::ends;

         FILE* f = _wfopen(filename.str().c_str(), L"wb+");
         if(!f)
         {
             std::wcout << "Failed to open file for writing: " << filename.str().c_str() << std::endl;
             RETURN(FALSE);
         }
         int bytesWritten = fwrite(pPrevCertContext->pbCertEncoded, 1, pPrevCertContext->cbCertEncoded, f);
         fclose(f);
         if(bytesWritten != pPrevCertContext->cbCertEncoded)
         {
             std::cout << "Failed to write file" << std::endl;
             RETURN(FALSE);
         }

         RETURN(TRUE); 
    }  

    //usage: DumpCertsFromSst <output directory> <SST file 1> ... <SST file n>
    int _tmain(int argc, _TCHAR* argv[])
    {
        SECURITY_ATTRIBUTES sa;   
        memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
        sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        sa.bInheritHandle = FALSE;  

        if(argc < 3)
        {
            std::cout << "At least two arguments must be provided: outputDirectory sstFile1 ... sstFileN etc" << std::endl;
            return 0;
        }

        TCHAR* outputDir = argv[1];

        for(int ii = 2; ii < argc; ++ii)
        {
            HANDLE       hFile = NULL;
            HCERTSTORE   hFileStore = NULL;
            LPCWSTR      pszFileName = argv[ii];

            //Open file
            hFile = CreateFile(pszFileName, GENERIC_READ, 0, &sa, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);                      
            if(INVALID_HANDLE_VALUE == hFile)
            {
                std::wcout << "Failed to open file: " << pszFileName  << std::endl;
                continue;
            }
            else
            {
                std::wcout << "Processing file: " << pszFileName  << std::endl;
            }

            //open certificate store
            hFileStore = CertOpenStore(CERT_STORE_PROV_FILE, 0, NULL, CERT_STORE_READONLY_FLAG, hFile);
            if(NULL == hFileStore)
            {
                CloseHandle(hFile);
                continue;
            }

            int count = 0;
            PCCERT_CONTEXT pPrevCertContext = NULL;
            pPrevCertContext = CertEnumCertificatesInStore(hFileStore, pPrevCertContext);
            while(NULL != pPrevCertContext)
            {
                if(WriteToFileWithHashAsFilename(pPrevCertContext, outputDir))
                    ++count;

                pPrevCertContext = CertEnumCertificatesInStore(hFileStore, pPrevCertContext);
            }

            std::wcout << "Wrote " << count << " certificates" << std::endl;
            CloseHandle(hFile);
            CertCloseStore(hFileStore, 0);
        }

        return 1;
    }
于 2013-01-29T16:06:49.153 に答える