Exemple #1
0
void Widget::on_IVErr_clicked()
{
    BYTE *iv, *srcData, *newData, *blockData1, *blockData2;
    DWORD ivLen, blockLen = 0;
    HCRYPTPROV hCryptProv;
    HCRYPTKEY hKey, newHKey;
    QVector<int> values;
    QFile myFile(fName);

    plot->clear();
    if (myFile.exists())
        myFile.open(QIODevice::ReadOnly);
    else
    {
        QMessageBox::critical(0, "Ошибка", "Файл не выбран", QMessageBox::Ok);
        return;
    }
    CryptAcquireContext(&hCryptProv, NULL, MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
    CryptGenKey(hCryptProv, CALG_AES_256, 0, &hKey);
    CryptEncrypt(hKey, 0, true, 0, NULL, &blockLen, myFile.size());
    srcData = new BYTE[block * blockLen];
    newData = new BYTE[block * blockLen];
    blockData1  = new BYTE[blockLen];
    blockData2  = new BYTE[blockLen];
    myFile.read((char*)srcData, block * blockLen);
    myFile.close();
    memcpy((char*)newData, (char*)srcData, block * blockLen);
    newData[0] = -newData[0];
    CryptDuplicateKey(hKey, NULL, 0, &newHKey);
    CryptGetKeyParam(newHKey, KP_IV, NULL, &ivLen, 0);
    iv = new BYTE[ivLen];
    CryptGetKeyParam(newHKey, KP_IV, iv, &ivLen, 0);
    iv[0] = -iv[0];
    CryptSetKeyParam(newHKey, KP_IV, iv, 0);
    for (uint i = 0; i < (block * blockLen); i++)
    {
        CryptEncrypt(hKey, 0, i < 2, 0, srcData + i, &blockLen, block * blockLen);
        CryptEncrypt(newHKey, 0, i < 2, 0, newData + i, &blockLen, block * blockLen);
    }
    for(uint i = 0; i < (block * blockLen); i += blockLen)
    {
        int k = 0;
        memcpy(blockData1, srcData + i, blockLen);
        memcpy(blockData2, newData + i, blockLen);
        for (uint j = i; j < (i + blockLen); j++)
            k += trueBitsCount(srcData[j] ^ newData[j]);
        values.push_back(k);
    }
    delete[] newData;
    delete[] srcData;
    delete[] blockData1;
    delete[] blockData2;
    delete[] iv;
    CryptReleaseContext(hCryptProv, 0);
    CryptDestroyKey(hKey);
    CryptDestroyKey(newHKey);
    DrawPlot(plot, values);
    plot->show();
}
Exemple #2
0
QByteArray QCSPPrivate::keyParam( HCRYPTKEY key, DWORD param, DWORD flags )
{
	DWORD size = 0;
	if( !CryptGetKeyParam( key, param, 0, &size, flags ) )
		return QByteArray();
	QByteArray data( size, 0 );
	if( !CryptGetKeyParam( key, param, LPBYTE(data.data()), &size, flags ) )
		return QByteArray();
	return data;
}
Exemple #3
0
// @pymethod object|PyCRYPTKEY|CryptGetKeyParam|Retrieves key parameters
// @rdesc Type of returned object is dependent on the requested attribute
PyObject *PyCRYPTKEY::PyCryptGetKeyParam(PyObject *self, PyObject *args, PyObject *kwargs)
{
	static char *keywords[]={"Param", "Flags", NULL};
	PyObject *ret=NULL;
	DWORD dwFlags=0, dwParam=0, dwDataLen=0;
	BYTE *pbData = NULL;
	HCRYPTKEY hcryptkey=((PyCRYPTKEY *)self)->GetHCRYPTKEY();

	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "k|k:CryptGetKeyParam", keywords,
		&dwParam,	// @pyparm int|Param||One of the KP_* constants
		&dwFlags))	// @pyparm int|Flags|0|Reserved, use only 0
		return NULL;
	if (!CryptGetKeyParam(hcryptkey, dwParam, pbData, &dwDataLen, dwFlags))
		return PyWin_SetAPIError("CryptGetKeyParam");

	pbData=(BYTE *)malloc(dwDataLen);
	if (pbData==NULL)
		return PyErr_Format(PyExc_MemoryError, "PyCRYPTKEY::CryptGetKeyParam: Unable to allocate %d bytes", dwDataLen);

	if (!CryptGetKeyParam(hcryptkey, dwParam, pbData, &dwDataLen, dwFlags)){
		PyWin_SetAPIError("CryptGetKeyParam",GetLastError());
		goto done;
		}

	switch (dwParam){
		case KP_ALGID:
		case KP_MODE:
		case KP_MODE_BITS:
		case KP_EFFECTIVE_KEYLEN:
		case KP_BLOCKLEN:
		case KP_PERMISSIONS:
		case KP_PADDING:
		case KP_KEYLEN:
			ret=Py_BuildValue("l",*((DWORD *)pbData));
			break;
		case KP_P:
		case KP_Q:
		case KP_G:
		case KP_IV:
		case KP_SALT:
			ret=PyString_FromStringAndSize((char *)pbData,dwDataLen);
			break;
		default:
			PyErr_SetString(PyExc_NotImplementedError, "The Param specified is not yet supported");
			break;
		}
	done:
	if (pbData != NULL)
		free(pbData);
	return ret;
}
Exemple #4
0
static void
keyInfo( HCRYPTKEY key )
{
    BYTE	buffer[ 1024 ];
    DWORD	length;

    length = sizeof( buffer );

    if ( ! CryptGetKeyParam( key, KP_BLOCKLEN, buffer, &length, 0 ) )
    {
	fprintf( stderr, "CryptGetKeyParam BLOCKLEN failed: 0x%x\n", GetLastError() );
	exit( 1 );
    }

    printf( "Key Block Size: %d\n", *(DWORD *)buffer / 8 );
    length = sizeof( buffer );

    if ( ! CryptGetKeyParam( key, KP_MODE, buffer, &length, 0 ) )
    {
	fprintf( stderr, "CryptGetKeyParam MODE failed: 0x%x\n", GetLastError() );
	exit( 1 );
    }

    printf( "Key Mode: %d\n", *(DWORD *)buffer );
    length = sizeof( buffer );

    if ( ! CryptGetKeyParam( key, KP_PADDING, buffer, &length, 0 ) )
    {
	fprintf( stderr, "CryptGetKeyParam PADDING failed: 0x%x\n", GetLastError() );
	exit( 1 );
    }

    printf( "Key Padding Type: %d\n", *(DWORD *)buffer );
    length = sizeof( buffer );

    if ( ! CryptGetKeyParam( key, KP_IV, buffer, &length, 0 ) )
    {
	fprintf( stderr, "CryptGetKeyParam PADDING failed: 0x%x\n", GetLastError() );
	exit( 1 );
    }

    printf( "Key IV: \n" );
    hexDump( length, buffer );
}
Exemple #5
0
/**
 * Returns the length in bytes of the modulus for the given RSA key
 */
int RSA_keylen(const RSA_key_t rsa)
{
    DWORD keylen, bsize;

    bsize = sizeof(keylen);
    if (!CryptGetKeyParam(rsa, KP_KEYLEN, (BYTE *)&keylen, &bsize, 0)) {
        mserror("CryptGetKeyParam failed");
        return 0;
    }
    return keylen / 8;
}
Exemple #6
0
static BOOL __stdcall
CryptSetKeyParam_done(BOOL retval,
                      HCRYPTKEY hKey,
                      DWORD dwParam,
                      BYTE *pbData,
                      DWORD dwFlags)
{
    DWORD err = GetLastError();
    int ret_addr = *((DWORD *) ((DWORD) &retval - 4));

    if (retval && !called_internally(ret_addr))
    {
        const char *data = NULL;
        int data_len = 0;
        DWORD block_len, len = 4;

        switch (dwParam)
        {
            case KP_IV:
                if (CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE *) &block_len, &len, 0))
                {
                    data = (const char *) pbData;
                    data_len = block_len / 8;
                }
                break;
            case KP_PERMISSIONS:
            case KP_ALGID:
            case KP_PADDING:
            case KP_MODE:
            case KP_MODE_BITS:
                data = (const char *) pbData;
                data_len = 4;
                break;
            default:
                break;
        }

        message_logger_log(_T("CryptSetKeyParam"), (char *) &retval - 4, (DWORD) hKey,
            MESSAGE_TYPE_PACKET, MESSAGE_CTX_INFO, PACKET_DIRECTION_INVALID,
            NULL, NULL, data, data_len,
            _T("hKey=0x%p, dwParam=%s, dwFlags=0x%08x"),
            hKey, key_param_to_string(dwParam), dwFlags);
    }

    SetLastError(err);
    return retval;
}
Exemple #7
0
PCCERT_CONTEXT DigiCrypt_ReadCertFromCard(void)
{
HCRYPTPROV hCryptProv;
BYTE       *pbData = NULL;   
HCRYPTKEY  hKey;          
DWORD cbData = 0;
DWORD dwKeyType=0;
DWORD dwErrCode=0;
DWORD cspType=0;
DWORD cspFlag=CRYPT_SILENT;
char *psCspName = NULL;
char *psKeyContainer;
BOOL fRes = FALSE;
PCCERT_CONTEXT  pCertContext = NULL; 
CRYPT_KEY_PROV_INFO KeyProvInfo;
LPWSTR wszContainerName=NULL;
LPWSTR wszProvName=NULL;
DWORD cchContainerName;
DWORD cchCSPName;
HCRYPTPROV hProv;


DigiCrypt_ReleaseFirstAllowedCSP();

psCspName=DigiCrypt_GetFirstAllowedCSPNameNew();

//very dummy thing.. i check from csp creators why i should do so...
if(!lstrcmp(psCspName,"EstEID Card CSP"))
   fRes = CryptAcquireContext(&hProv,"XXX",psCspName,2, CRYPT_SILENT);
// end dummy//

if (psCspName == NULL || strstr(psCspName,psData_Est_CSP_Name) == NULL)
  return(pCertContext);

cspType=DigiCrypt_FindContext_GetCSPType(psCspName);

psKeyContainer=DigiCrypt_GetDefaultKeyContainerName(psCspName);

fRes = CryptAcquireContext(&hCryptProv,psKeyContainer,psCspName,cspType, CRYPT_SILENT);
if (fRes == FALSE)
  return(pCertContext);

fRes=CryptGetUserKey(hCryptProv, AT_SIGNATURE, &hKey);
if (fRes == TRUE)
  {
  fRes=CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &cbData, 0);
  if (fRes == TRUE)
    {
    pbData = (unsigned char*)malloc(cbData);
    if (pbData == NULL)
      fRes = FALSE;
    }
  if (fRes == TRUE)
    fRes=CryptGetKeyParam(hKey, KP_CERTIFICATE, pbData, &cbData, 0);
  if (fRes == TRUE)
    {
    pCertContext = CertCreateCertificateContext(MY_ENCODING_TYPE,pbData,cbData);
    if (pCertContext != NULL)
      { 
	  wszContainerName=NULL;
	  wszProvName=NULL;
	  cchContainerName = (lstrlen(psKeyContainer) + 1)  * sizeof(WCHAR);
	  cchCSPName = (lstrlen(psCspName) + 1) * sizeof(WCHAR);
      wszContainerName = (LPWSTR) malloc(cchContainerName);
      wszProvName = (LPWSTR) malloc(cchCSPName);
      mbstowcs(wszContainerName, psKeyContainer,cchContainerName);
	  mbstowcs(wszProvName, psCspName, cchCSPName);
      ZeroMemory((PVOID)&KeyProvInfo, sizeof(CRYPT_KEY_PROV_INFO));
      KeyProvInfo.pwszContainerName = (LPWSTR) wszContainerName;
      KeyProvInfo.pwszProvName      = (LPWSTR) wszProvName;
      KeyProvInfo.dwProvType        = PROV_RSA_SIG;
      KeyProvInfo.dwFlags           = 0;
      KeyProvInfo.dwKeySpec         = dwKeyType;
      fRes = CertSetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID, 0, (const void *) &KeyProvInfo);
      if (wszContainerName != NULL)
        free(wszContainerName);
      if (wszProvName != NULL)
        free(wszProvName);

      }
    }
  }

//if (pCertContext != NULL)
//  DigiCrypt_AddCertToStore(pCertContext);
if (fRes == FALSE && pCertContext != NULL)
  {
  CertFreeCertificateContext(pCertContext);
  pCertContext = NULL;
  }
if (pbData != NULL)
  free(pbData);
if (hCryptProv != 0)
  CryptReleaseContext(hCryptProv, 0);
return(pCertContext);
}
int WriteDebugInfo ()
{
//do some "crypto stuff" and log the output to a file for debugging
	
	const IN_BUFFER_SIZE    = 2048;
	const OUT_BUFFER_SIZE   = IN_BUFFER_SIZE + 64; // extra padding
	HANDLE	   hKeyFile = 0;
    BYTE       pbBuffer[OUT_BUFFER_SIZE];
	BOOL          finished = 1;
    HCRYPTPROV    hProvider = 0;
    HCRYPTKEY     hKey = 0, hExchangeKey = 0;
    DWORD         dwByteCount;
	long	rc=0;
	char * keyFile = "crypto.key";
	const char *  test = "This is a test...";
	char sProgramFiles[KEYFILENAME_SIZE];

/////////////////////////////
DWORD dwMode;
BYTE pbData[16];
DWORD dwCount;
DWORD i;
//////////////////////////////

	LOGIT = true;
	DEBUGIT = true;


	PrintLog((DEST,"%s",WindowsName[WhatWindowsVer()]));
	WinVer();

	InitVars(CSP_NAME, &iWinVer, &iCryptVer, &MAXKEYLEN);

	DebugLog((DEST,"CSP=%s WinVer=%d CryptVer=%d MaxKeyLen=%d",CSP_NAME, iWinVer, iCryptVer, MAXKEYLEN));

	DebugLog((DEST,"Testing some environment variables."));
	GetEnvVar(PROGRAMFILES, sProgramFiles, BufSize);
	GetEnvVar("temp", sProgramFiles, BufSize);
	GetEnvVar("path", sProgramFiles, BufSize);

	CreateKey(keyFile, MAXKEYLEN);

	DebugLog((DEST,"PrepContext"));
	PrepContext(iWinVer, &hProvider);

	hKeyFile = CreateFile(keyFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	DebugLog((DEST,"ImportCryptKey"));
	ImportCryptKey(hProvider, &hKey, hKeyFile);

	CloseHandle(hKeyFile);

////////////////////////////////////////////////////////
// Read the cipher mode.
dwCount = sizeof(DWORD);
if(!CryptGetKeyParam(hKey, KP_MODE, (BYTE *)&dwMode, &dwCount, 0)) {
    printf("Error %x during CryptGetKeyParam!\n", GetLastError());
    return 1;
}

// Print out the cipher mode.
printf("Default cipher mode: %d\n", dwMode);

// Read the salt.
dwCount = 16;
if(!CryptGetKeyParam(hKey, KP_SALT, pbData, &dwCount, 0)) {
    printf("Error %x during CryptGetKeyParam!\n", GetLastError());
    return 1;
}
// Print out the initialization vector.
printf("Default IV:");
for(i=0;i<dwCount;i++) printf("%2.2x ",pbData[i]);
printf("\n");

// Read the initialization vector.
dwCount = 16;
if(!CryptGetKeyParam(hKey, KP_IV, pbData, &dwCount, 0)) {
    printf("Error %x during CryptGetKeyParam!\n", GetLastError());
    return 1;
}
// Print out the initialization vector.
printf("Default IV:");
for(i=0;i<dwCount;i++) printf("%2.2x ",pbData[i]);
printf("\n");

// Set the cipher mode.
dwMode = CRYPT_MODE_OFB;
if(!CryptSetKeyParam(hKey, KP_MODE, (BYTE *)&dwMode, 0)) {
    printf("Error %x during CryptSetKeyParam!\n", GetLastError());
    return 1;
}

// Read the cipher mode.
dwCount = sizeof(DWORD);
if(!CryptGetKeyParam(hKey, KP_MODE, (BYTE *)&dwMode, &dwCount, 0)) {
    printf("Error %x during CryptGetKeyParam!\n", GetLastError());
    return 1;
}

// Print out the cipher mode.
printf("Default cipher mode: %d\n", dwMode);

dwCount = 16;
BYTE pbIV[17];

CryptGenRandom(hProvider, dwCount, pbIV);

if(!CryptSetKeyParam(hKey, KP_IV, pbIV, 0)) {
    printf("Error %x during CryptGetKeyParam!\n", GetLastError());
    return 1;
}

// Read the initialization vector.
dwCount = 16;
if(!CryptGetKeyParam(hKey, KP_IV, pbData, &dwCount, 0)) {
    printf("Error %x during CryptGetKeyParam!\n", GetLastError());
    return 1;
}
// Print out the initialization vector.
printf("Default IV:");
for(i=0;i<dwCount;i++) printf("%2.2x ",pbData[i]);
printf("\n");

if(!CryptSetKeyParam(hKey, KP_SALT, pbIV, 0)) {
    printf("Error %x during CryptGetKeyParam!\n", GetLastError());
    return 1;
}

// Read the salt.
dwCount = 16;
if(!CryptGetKeyParam(hKey, KP_SALT, pbData, &dwCount, 0)) {
    printf("Error %x during CryptGetKeyParam!\n", GetLastError());
    return 1;
}
// Print out the initialization vector.
printf("Default IV:");
for(i=0;i<dwCount;i++) printf("%2.2x ",pbData[i]);
printf("\n");

////////////////////////////////////////////

	strcpy((char *)pbBuffer, test);
	DebugLog((DEST,"%s",(char *)pbBuffer));

	dwByteCount = strlen((char *)pbBuffer);
	rc = CryptEncrypt(hKey, 0, finished, 0, pbBuffer, &dwByteCount, OUT_BUFFER_SIZE);
	DebugLog((DEST,"Encrypted buffer"));

	rc = CryptDecrypt(hKey, 0, finished, 0, pbBuffer, &dwByteCount);
	DebugLog((DEST,"Decrypted buffer"));

	DebugLog((DEST,"%s",(char *)pbBuffer));

	if (strcmp((char *)pbBuffer,test) ==0)
	{
		DebugLog((DEST,"Encrypt/Decrypt Succeeded"));
	}
	else
	{
		DebugLog((DEST,"Encrypt/Decrypt Failed"));
	}

	CleanupCryptoKey(hExchangeKey);
    CleanupCryptoKey(hKey);
	CleanupCryptoContext(hProvider);

	DebugLog((DEST,"Listing Providers."));
	ListProviders();
   
   return(0);
}
Exemple #9
0
static int
xmlSecMSCryptoKWDes3BlockDecrypt(void * context,
                               const xmlSecByte * iv, xmlSecSize ivSize,
                               const xmlSecByte * in, xmlSecSize inSize,
                               xmlSecByte * out, xmlSecSize outSize) {
    xmlSecMSCryptoKWDes3CtxPtr ctx = (xmlSecMSCryptoKWDes3CtxPtr)context;
    DWORD dwBlockLen, dwBlockLenLen, dwCLen;
    HCRYPTKEY cryptKey = 0;
    int ret;

    xmlSecAssert2(ctx != NULL, -1);
    xmlSecAssert2(xmlSecBufferGetData(&(ctx->keyBuffer)) != NULL, -1);
    xmlSecAssert2(xmlSecBufferGetSize(&(ctx->keyBuffer)) >= XMLSEC_KW_DES3_KEY_LENGTH, -1);
    xmlSecAssert2(iv != NULL, -1);
    xmlSecAssert2(ivSize >= XMLSEC_KW_DES3_IV_LENGTH, -1);
    xmlSecAssert2(in != NULL, -1);
    xmlSecAssert2(inSize > 0, -1);
    xmlSecAssert2(out != NULL, -1);
    xmlSecAssert2(outSize >= inSize, -1);

    /* Import this key and get an HCRYPTKEY handle, we do it again and again 
       to ensure we don't go into CBC mode */
    if (!xmlSecMSCryptoImportPlainSessionBlob(ctx->desCryptProvider,
        ctx->pubPrivKey,
        ctx->desAlgorithmIdentifier,
        xmlSecBufferGetData(&ctx->keyBuffer),
        xmlSecBufferGetSize(&ctx->keyBuffer),
        TRUE,
        &cryptKey))  {

        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecMSCryptoImportPlainSessionBlob",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(-1);
    }
    xmlSecAssert2(cryptKey != 0, -1);

    /* iv len == block len */
    dwBlockLenLen = sizeof(DWORD);
    if (!CryptGetKeyParam(cryptKey, KP_BLOCKLEN, (BYTE *)&dwBlockLen, &dwBlockLenLen, 0)) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "CryptGetKeyParam",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        CryptDestroyKey(cryptKey);
        return(-1);
    }

    /* set IV */
    if((ivSize < dwBlockLen / 8) || (!CryptSetKeyParam(cryptKey, KP_IV, iv, 0))) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "CryptSetKeyParam",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    "ivSize=%d, dwBlockLen=%d", 
                    ivSize, dwBlockLen / 8);
        CryptDestroyKey(cryptKey);
        return(-1);
    }

    /* Set process last block to false, since we handle padding ourselves, and MSCrypto padding
     * can be skipped. I hope this will work .... */
    if(out != in) {
        memcpy(out, in, inSize);
    }
    dwCLen = inSize;
    if(!CryptDecrypt(cryptKey, 0, FALSE, 0, out, &dwCLen)) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "CryptEncrypt",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        CryptDestroyKey(cryptKey);
        return(-1);
    }

    /* cleanup */
    CryptDestroyKey(cryptKey);
    return(dwCLen);
}
void gen_aes256_key_iv()
{
    HCRYPTPROV provider = NULL;
    HCRYPTKEY hKey = NULL;
    HCRYPTKEY newHKey = NULL;
    DWORD ivLen, blockLen = 0;
    BYTE* iv = NULL;
    BYTE* buffer = NULL;
    char* cipherText = NULL;
    unsigned long cLen;
    char* cipherText2 = NULL;
    unsigned long cLen2;
    char* cipherText3 = NULL;
    unsigned long cLen3;
    char* cipherText4 = NULL;
    unsigned long cLen4;

    if (!OpenCryptContext(&provider)) {
        printf("CryptAcquireContext() failed:");
        goto Exit0;
    }

    // 生成随机密钥
    // 还可以从通过给定密码 HASH 后获取 AES 密钥
    if (!CryptGenKey(provider, CALG_AES_256, CRYPT_EXPORTABLE, &hKey)) {
        goto Exit0;
    }

    // Get the key size.
    DWORD buffer_size = 0;

    if (!CryptExportKey(hKey, 0, PLAINTEXTKEYBLOB, 0, NULL, &buffer_size)) {
        printf("CryptExportKey failed.\n");
        goto Exit0;
    }

    // Export the key.
    buffer = new BYTE[buffer_size];

    if (!CryptExportKey(hKey, 0, PLAINTEXTKEYBLOB, 0, buffer, &buffer_size)) {
        printf("CryptExportKey2 failed.\n");
        goto Exit0;
    }

    plaintext_blob_t* blob = (plaintext_blob_t*)buffer;
    printf("aes Key:\n");
    printf("\nchar aes256_key[]=\n{");
    print_bin2c(blob->rgbKeyData, blob->cbKeySize);
    printf("};");
    printf("\n\n");

    // base64 编码
    if (!Base64EncodeA(&cipherText, &cLen, blob->rgbKeyData, blob->cbKeySize))  {
        //xfree(encrypted);
        xstrerror("Base64EncodeA()");
        goto Exit0;
    }

    printf("aes base64 Key:\n");
    printf(cipherText);
    printf("\n\n");

    // Hex 编码
    if (!Bin2Hex(&cipherText3, &cLen3, blob->rgbKeyData, blob->cbKeySize)) {
        xstrerror("Bin2Hex()");
        goto Exit0;
    }

    printf("aes hex Key:\n");
    printf(cipherText3);
    printf("\n\n");

    // 从随机密钥获取 IV 长度
    if (!CryptGetKeyParam(hKey, KP_IV, NULL, &ivLen, 0)) {
        goto Exit0;
    }

    iv = new BYTE[ivLen];
    ZeroMemory(iv, ivLen);

    if (!CryptGenRandom(provider, ivLen, iv)) {
        goto Exit0;
    }

    printf("aes IV:\n");
    printf("\nchar aes256_iv[]=\n{");
    print_bin2c(iv, ivLen);
    printf("};");
    printf("\n\n");

    if (!Base64EncodeA(&cipherText2, &cLen2, iv, ivLen))    {
        xstrerror("Base64EncodeA()");
        goto Exit0;
    }

    printf("aes base64 iv:\n");
    printf(cipherText2);
    printf("\n\n");

    // Hex 编码
    if (!Bin2Hex(&cipherText4, &cLen4, iv, ivLen)) {
        xstrerror("Bin2Hex()");
        goto Exit0;
    }

    printf("aes hex iv:\n");
    printf(cipherText4);
    printf("\n\n");
    DWORD LenBlockAES = 0;
    DWORD dwCount = sizeof(DWORD);

    if (!CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&LenBlockAES, &dwCount, 0)) {
        goto Exit0;
    }

    printf("aes block data len: %d\n", LenBlockAES);
Exit0:

    if (cipherText4) {
        xfree(cipherText4);
        cipherText4 = NULL;
    }

    if (cipherText3) {
        xfree(cipherText3);
        cipherText3 = NULL;
    }

    if (cipherText2) {
        xfree(cipherText2);
        cipherText2 = NULL;
    }

    if (cipherText) {
        xfree(cipherText);
        cipherText = NULL;
    }

    if (buffer) {
        delete[] buffer;
        buffer = NULL;
    }

    if (iv) {
        delete[] iv;
        iv = NULL;
    }

    if (hKey) {
        CryptDestroyKey(hKey);
    }

    if (provider) {
        CryptReleaseContext(provider, 0);
    }

    return;
}
void mod_mimikatz_crypto::listAndOrExportKeys(vector<wstring> * arguments, bool exportKeys)
{
	bool isMachine = false;
	DWORD providerType = PROV_RSA_FULL;
	wstring provider = MS_ENHANCED_PROV;

	switch (arguments->size())
	{
		case 1:
			isMachine = true;
		case 0:
			break;
		case 3:
			isMachine = true;
			arguments->erase(arguments->begin());
		case 2:
			mod_cryptoapi::getProviderString(arguments->front(), &provider);
			mod_cryptoapi::getProviderTypeFromString(arguments->back(), &providerType);
			break;
		default :
			(*outputStream) << L"Erreur d\'arguments, attendu : [machine] [provider providerType]" << endl;
			return;
	}
	
	
	wstring type = (isMachine ? L"machine" : L"user");

	vector<wstring> * monVectorKeys = new vector<wstring>();

	/* CryptoAPI */
	(*outputStream) << L"[" << type << L"] Clés CryptoAPI :" << endl;
	if(mod_cryptoapi::getVectorContainers(monVectorKeys, isMachine))
	{
		DWORD i;
		vector<wstring>::iterator monContainer;
		for(i = 0, monContainer = monVectorKeys->begin(); monContainer != monVectorKeys->end(); ++monContainer, ++i)
		{
			(*outputStream) << L"\t - " << *monContainer << endl;

			HCRYPTPROV hCryptKeyProv = NULL;
			if(CryptAcquireContext(&hCryptKeyProv, monContainer->c_str(), provider.c_str(), providerType, NULL | (isMachine ? CRYPT_MACHINE_KEYSET : NULL)))
			{
				HCRYPTKEY maCle = NULL;
				for(DWORD ks = AT_KEYEXCHANGE; (ks <= AT_SIGNATURE) && !maCle; ks++)
				{
					if(CryptGetUserKey(hCryptKeyProv, ks, &maCle))
					{
						(*outputStream) << L"\t\tType          : " << mod_crypto::KeyTypeToString(ks) << endl;
						DWORD param = 0, taille = sizeof(param);
						if(CryptGetKeyParam(maCle, KP_PERMISSIONS, reinterpret_cast<BYTE *>(&param), &taille, NULL))
							(*outputStream) << L"\t\tExportabilité : " << (param & CRYPT_EXPORT ? L"OUI" : L"NON") << endl;
						if(CryptGetKeyParam(maCle, KP_KEYLEN, reinterpret_cast<BYTE *>(&param), &taille, NULL))
							(*outputStream) << L"\t\tTaille clé    : " << param << endl;

						if(exportKeys)
						{
							bool reussite = false;
							BYTE * monExport = NULL;
							DWORD tailleExport = 0;

							wstringstream monBuff;
							wstring containerName = *monContainer;
							sanitizeFileName(&containerName);

							monBuff << L"capi_" << type << L'_' << i << L'_' << containerName << L".pvk";
						
							if(mod_cryptoapi::getPrivateKey(maCle, &monExport, &tailleExport))
							{
								reussite = mod_crypto::PrivateKeyBlobToPVK(monExport, tailleExport, monBuff.str(), ks);
								delete[] monExport;
							}

							(*outputStream) << L"\t\tExport privé dans  \'" << monBuff.str() << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
							if(!reussite)
							{
								(*outputStream) << L"\t\t\tmod_cryptoapi::getPrivateKey/PrivateKeyBlobToPVK : " << mod_system::getWinError() << endl;
							}
						}
					}
				}

				if(maCle)
					CryptDestroyKey(maCle);
				else
					(*outputStream) << L"\t\t* Erreur de clé ; " << mod_system::getWinError() << endl;


				CryptReleaseContext(hCryptKeyProv, 0);
			}
			else (*outputStream) << L"\t\t* Erreur d\'acquisition de la clé ; " << mod_system::getWinError() << endl;
		}
	}
	else (*outputStream) << L"mod_cryptoapi::getVectorContainers : " << mod_system::getWinError() << endl;

	/* CryptoNG */
	if(mod_cryptong::isNcrypt)
	{
		(*outputStream) << endl;
		monVectorKeys->clear();

		(*outputStream) << L"[" << type << L"] Clés CNG :" << endl;
		if(mod_cryptong::getVectorContainers(monVectorKeys, isMachine))
		{
			DWORD i;
			vector<wstring>::iterator monContainer;
			for(i = 0, monContainer = monVectorKeys->begin(); monContainer != monVectorKeys->end(); ++monContainer, ++i)
			{
				(*outputStream) << L"\t - " << *monContainer << endl;

				NCRYPT_KEY_HANDLE maCle;
				if(mod_cryptong::getHKeyFromName(*monContainer, &maCle, isMachine))
				{
					bool exportable = false;
					DWORD size = 0;

					if(mod_cryptong::isKeyExportable(&maCle, &exportable))
						(*outputStream) << L"\t\tExportabilité : " << (exportable ? L"OUI" : L"NON") << endl;
					if(mod_cryptong::getKeySize(&maCle, &size))
						(*outputStream) << L"\t\tTaille clé    : " << size << endl;

					if(exportKeys)
					{
						bool reussite = false;
						BYTE * monExport = NULL;
						DWORD tailleExport = 0;

						wstringstream monBuff;
						monBuff << L"cng_" << type << L'_' << i << L'_' << *monContainer << L".pvk";

						if(mod_cryptong::getPrivateKey(maCle, &monExport, &tailleExport))
						{
							reussite = mod_crypto::PrivateKeyBlobToPVK(monExport, tailleExport, monBuff.str());
							delete[] monExport;
						}

						(*outputStream) << L"\t\tExport privé dans  \'" << monBuff.str() << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
						if(!reussite)
						{
							(*outputStream) << L"\t\t\tmod_cryptong::getPrivateKey/PrivateKeyBlobToPVK : " << mod_system::getWinError() << endl;
						}
					}	
					mod_cryptong::NCryptFreeObject(maCle);
				}
			}
		}
		else (*outputStream) << L"mod_cryptong::getVectorContainers : " << mod_system::getWinError() << endl;
	}

	delete monVectorKeys;
}
Exemple #12
0
DWORD ShowCertsDlg(LPCTSTR szProviderName,
				  LPCTSTR szReaderName /* Can be NULL */
				  )
{
	HCRYPTPROV HMainCryptProv = NULL;
	BOOL bStatus = FALSE;
	LPTSTR szMainContainerName = NULL;
	CHAR szContainerName[1024];
	DWORD dwContainerNameLen = sizeof(szContainerName);
	DWORD dwErr = 0;
	DWORD dwFlags = CRYPT_FIRST;
	PCCERT_CONTEXT pContextArray[128];
	DWORD dwContextArrayLen = 0;
	HCRYPTPROV hProv = NULL;
	HCRYPTKEY hKey = NULL;
	LPBYTE pbCert = NULL;
	DWORD dwCertLen = 0;
	PCCERT_CONTEXT pCertContext = NULL;
	DWORD pKeySpecs[2] = { AT_KEYEXCHANGE, AT_SIGNATURE};

	if (szReaderName)
	{
		size_t ulNameLen = _tcslen(szReaderName);
		szMainContainerName = (LPTSTR) LocalAlloc(0, (ulNameLen + 6) * sizeof(TCHAR));
		if (!szMainContainerName)
		{
			return GetLastError();
		}
		_stprintf(szMainContainerName, _T("\\\\.\\%s\\"), szReaderName);
	}			

	bStatus = CryptAcquireContext(&HMainCryptProv,szMainContainerName,szProviderName,PROV_RSA_FULL,0);

	if (!bStatus)
	{
		dwErr = GetLastError();
		goto end;
	}

	/* Enumerate all the containers */
	while (CryptGetProvParam(HMainCryptProv,PP_ENUMCONTAINERS,(LPBYTE) szContainerName,&dwContainerNameLen,dwFlags) &&(dwContextArrayLen < 128))
	{
#ifndef _UNICODE
		if (CryptAcquireContext(&hProv,
				szContainerName,
				szProviderName,
				PROV_RSA_FULL,
				0))
#else
		// convert the container name to unicode
		int wLen = MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, NULL, 0);
		LPWSTR szWideContainerName = (LPWSTR) LocalAlloc(0, wLen * sizeof(WCHAR));
		MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, szWideContainerName, wLen);

		// Acquire a context on the current container
		if (CryptAcquireContext(&hProv,szWideContainerName,szProviderName,PROV_RSA_FULL,0))
#endif
		{
			// Loop over all the key specs
			for (int i = 0; i < 2; i++)
			{
				if (CryptGetUserKey(hProv,pKeySpecs[i],&hKey) )
				{
					if (CryptGetKeyParam(hKey,KP_CERTIFICATE,NULL,&dwCertLen,0))
					{
						pbCert = (LPBYTE) LocalAlloc(0, dwCertLen);
						if (!pbCert)
						{
							dwErr = GetLastError();
							goto end;
						}
						if (CryptGetKeyParam(hKey,KP_CERTIFICATE,pbCert,&dwCertLen,0))
						{
							pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, pbCert,dwCertLen);
							if (pCertContext)
							{
								pContextArray[dwContextArrayLen++] = pCertContext;

								CRYPT_KEY_PROV_INFO ProvInfo;
								ProvInfo.pwszContainerName = szWideContainerName;
								ProvInfo.pwszProvName = L"Microsoft Base Smart Card Crypto Provider";
								ProvInfo.dwProvType = PROV_RSA_FULL;
								ProvInfo.dwFlags = 0;
								ProvInfo.dwKeySpec = AT_SIGNATURE;
								ProvInfo.cProvParam = 0;
								ProvInfo.rgProvParam = NULL;
								
								CertSetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID, 0, &ProvInfo);

								HCERTSTORE dest = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL,
								CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_CURRENT_USER,L"My");
								if(CertAddCertificateContextToStore(dest, pCertContext,CERT_STORE_ADD_REPLACE_EXISTING, NULL))
								{
									//char certName[1024];
									//LPWSTR certName = (LPWSTR)new wchar_t[1024];
									LPTSTR certName;
									int cbSize = CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,NULL,0);
									certName = (LPTSTR)malloc(cbSize * sizeof(TCHAR));

									if (CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,certName,sizeof(certName)))
									{
									}
									printf("Installed certificate.");
								}
								else
									printf("Error while adding certificate to store");
							}
						}
						LocalFree(pbCert);
					}
					CryptDestroyKey(hKey);
					hKey = NULL;
				}
			}
			CryptReleaseContext(hProv, 0);
			hProv = NULL;
		}

#ifdef _UNICODE
		LocalFree(szWideContainerName);
#endif
		
		// prepare parameters for the next loop
		dwContainerNameLen = sizeof(szContainerName);
		dwFlags = 0;
	}

	if (dwContextArrayLen == 0)
		printf("No certificate contexts found on card\n");
	
end:
	while (dwContextArrayLen--)
	{
		CertFreeCertificateContext(pContextArray[dwContextArrayLen]);
	}
	if (hKey)
		CryptDestroyKey(hKey);
	if (hProv)
		CryptReleaseContext(hProv, 0);
	if (szMainContainerName)
		LocalFree(szMainContainerName);
	if (HMainCryptProv)
		CryptReleaseContext(HMainCryptProv, 0);
	return dwErr;
}
Exemple #13
0
BOOL
xmlSecMSCryptoImportPlainSessionBlob(HCRYPTPROV hProv, HCRYPTKEY hPrivateKey,
                                     ALG_ID dwAlgId, LPBYTE pbKeyMaterial,
                                     DWORD dwKeyMaterial, BOOL bCheckKeyLength,
                                     HCRYPTKEY *hSessionKey) {
    ALG_ID dwPrivKeyAlg;
    LPBYTE keyBlob = NULL;
    DWORD keyBlobLen, rndBlobSize, dwSize, n;
    PUBLICKEYSTRUC* pubKeyStruc;
    ALG_ID* algId;
    DWORD dwPublicKeySize;
    DWORD dwProvSessionKeySize = 0;
    LPBYTE pbPtr;
    DWORD dwFlags;
    PROV_ENUMALGS_EX ProvEnum;
    HCRYPTKEY hTempKey = 0;
    BOOL fFound;
    BOOL res = FALSE;

    xmlSecAssert2(hProv != 0, FALSE);
    xmlSecAssert2(hPrivateKey != 0, FALSE);
    xmlSecAssert2(pbKeyMaterial != NULL, FALSE);
    xmlSecAssert2(dwKeyMaterial > 0, FALSE);
    xmlSecAssert2(hSessionKey != NULL, FALSE);

    /*  Double check to see if this provider supports this algorithm and key size */
    fFound = FALSE;
    dwFlags = CRYPT_FIRST;
    dwSize = sizeof(ProvEnum);
    while(CryptGetProvParam(hProv, PP_ENUMALGS_EX, (LPBYTE)&ProvEnum, &dwSize, dwFlags)) {
        if (ProvEnum.aiAlgid == dwAlgId) {
            fFound = TRUE;
            break;
        }
        dwSize = sizeof(ProvEnum);
        dwFlags = 0;
    }
    if(!fFound) {
        xmlSecMSCryptoError2("CryptGetProvParam", NULL,
                             "algId=%ld is not supported",
                             (long int)dwAlgId);
        goto done;
    }

    if(bCheckKeyLength) {
        /* We have to get the key size(including padding) from an HCRYPTKEY handle.
         * PP_ENUMALGS_EX contains the key size without the padding so we can't use it.
         */
        if(!CryptGenKey(hProv, dwAlgId, 0, &hTempKey)) {
            xmlSecMSCryptoError2("CryptGenKey", NULL,
                                 "algId=%ld",
                                 (long int)dwAlgId);
            goto done;
        }

        dwSize = sizeof(DWORD);
        if(!CryptGetKeyParam(hTempKey, KP_KEYLEN, (LPBYTE)&dwProvSessionKeySize, &dwSize, 0)) {
            xmlSecMSCryptoError2("CryptGetKeyParam(KP_KEYLEN)", NULL,
                                 "algId=%ld", (long int)dwAlgId);
            goto done;
        }
        CryptDestroyKey(hTempKey);
        hTempKey = 0;

        /* yell if key is too big */
        if ((dwKeyMaterial * 8) > dwProvSessionKeySize) {
            xmlSecInvalidSizeMoreThanError("Key value (bits)",
                                           (dwKeyMaterial * 8), dwProvSessionKeySize,
                                           NULL);
            goto done;
        }
    } else {
        dwProvSessionKeySize = dwKeyMaterial * 8;
    }

    /* Get private key's algorithm */
    dwSize = sizeof(ALG_ID);
    if(!CryptGetKeyParam(hPrivateKey, KP_ALGID, (LPBYTE)&dwPrivKeyAlg, &dwSize, 0)) {
        xmlSecMSCryptoError2("CryptGetKeyParam(KP_ALGID)", NULL,
                             "algId=%ld",
                             (long int)dwAlgId);
        goto done;
    }

    /* Get private key's length in bits */
    dwSize = sizeof(DWORD);
    if(!CryptGetKeyParam(hPrivateKey, KP_KEYLEN, (LPBYTE)&dwPublicKeySize, &dwSize, 0)) {
        xmlSecMSCryptoError2("CryptGetKeyParam(KP_KEYLEN)", NULL,
                             "algId=%ld",
                             (long int)dwAlgId);
        goto done;
    }

    /* 3 is for the first reserved byte after the key material and the 2 reserved bytes at the end. */
    if(dwPublicKeySize / 8 < dwKeyMaterial + 3) {
        xmlSecInvalidSizeLessThanError("Key value", dwPublicKeySize / 8, dwKeyMaterial + 3, NULL);
        goto done;
    }
    rndBlobSize = dwPublicKeySize / 8 - (dwKeyMaterial + 3);

    /* Simple key BLOBs, type SIMPLEBLOB, are used to store and transport session keys outside a CSP.
     * Base provider simple-key BLOBs are always encrypted with a key exchange public key. The pbData
     * member of the SIMPLEBLOB is a sequence of bytes in the following format:
     *
     * PUBLICKEYSTRUC  publickeystruc ;
     * ALG_ID algid;
     * BYTE encryptedkey[rsapubkey.bitlen/8];
     */

    /* calculate Simple blob's length */
    keyBlobLen = sizeof(PUBLICKEYSTRUC) + sizeof(ALG_ID) + (dwPublicKeySize / 8);

    /* allocate simple blob buffer */
    keyBlob = (LPBYTE)xmlMalloc(sizeof(BYTE) * keyBlobLen);
    if(keyBlob == NULL) {
        xmlSecMallocError(sizeof(BYTE) * keyBlobLen, NULL);
        goto done;
    }
    memset(keyBlob, 0, keyBlobLen);

    /* initialize PUBLICKEYSTRUC */
    pubKeyStruc             = (PUBLICKEYSTRUC*)(keyBlob);
    pubKeyStruc->bType      = SIMPLEBLOB;
    pubKeyStruc->bVersion   = 0x02;
    pubKeyStruc->reserved   = 0;
    pubKeyStruc->aiKeyAlg   = dwAlgId;

    /* Copy private key algorithm to buffer */
    algId                   = (ALG_ID*)(keyBlob + sizeof(PUBLICKEYSTRUC));
    (*algId)                = dwPrivKeyAlg;

    /* Place the key material in reverse order */
    pbPtr                   = (BYTE*)(keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(ALG_ID));
    for (n = 0; n < dwKeyMaterial; n++) {
        pbPtr[n] = pbKeyMaterial[dwKeyMaterial - n - 1];
    }
    pbPtr += dwKeyMaterial;

    /* skip reserved byte */
    pbPtr += 1;

    /* Generate random data for the rest of the buffer */
    if((rndBlobSize > 0) && !CryptGenRandom(hProv, rndBlobSize, pbPtr)) {
        xmlSecMSCryptoError2("CryptGenRandom", NULL,
                             "rndBlobSize=%ld",
                             (long int)rndBlobSize);
        goto done;
    }
    /* aleksey: why are we doing this? */
    for (n = 0; n < rndBlobSize; n++) {
        if (pbPtr[n] == 0) pbPtr[n] = 1;
    }

    /* set magic number at the end */
    keyBlob[keyBlobLen - 2] = 2;

    if(!CryptImportKey(hProv, keyBlob , keyBlobLen, hPrivateKey, CRYPT_EXPORTABLE, hSessionKey)) {
        xmlSecMSCryptoError2("CryptImportKey", NULL,
                             "algId=%ld",
                             (long int)dwAlgId);
        goto done;
    }

    /* success */
    res = TRUE;

done:
    if(hTempKey != 0) {
        CryptDestroyKey(hTempKey);
    }
    if(keyBlob != NULL) {
        xmlFree(keyBlob);
    }
    return(res);
}
Exemple #14
0
int  main (int argc, char *argv[])
{


    DWORD dwProvType = 75;   
    DWORD data_len = 0;			    
    BYTE *oid = NULL;			    
    DWORD dwBlobLen = 0;		    
    DWORD cAlg = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 31);

	LPCSTR SourceName = NULL;
	LPCSTR Psdw = NULL;

	HANDLE hCurrProc = GetCurrentProcess();
	char patch[] = {0x80,0xbd,0x1c,0x00,0x00,0x00,0x98,0x75,0x07,0xc6,0x85,0x1c,0x00,0x00,0x00,0x9c,0x90,0x90,0x90,0x90,0x90,0x90}; ///!!!
	int patchLen = sizeof(patch);
	DWORD previous = 0;

	DWORD writeAddr = 0x11BC2;// INITIALIZED with offset!!!  //0x611E1BC2;


	/// PARSE COMMAND PARAMETERS HERE
	for (int n = 1;n < argc;n++) {
		if (n+1 >= argc)
			break;
		if (strcmp(argv[n],"-p") == 0) {
			Psdw = argv[++n];
		}
		if (strcmp(argv[n],"-s") == 0) {
			SourceName = argv[++n];
		}
	}
	if (!Psdw || !SourceName) {
		printf("[!] Dude, u specified incorrect parameters :/\n\tUsage: %s -s <source container name> -p <container password>",argv[0]);
		exit(1);
	}


    if(!CryptAcquireContextA(
	&hProvResponder, 
	"\\\\.\\Registry\\DestCopy", //Hardcoded name for container we create!!!
	NULL,
	dwProvType,
	CRYPT_NEWKEYSET | CRYPT_SILENT))
    {
		HandleError("Error during CryptAcquireContext");
    }


    if(!CryptAcquireContextA(
	&hProvSender, 
	SourceName, 
	NULL, 
	dwProvType, 
	0)) 
    {
		HandleError("Error during CryptAcquireContext");
    }

	/// FIND ADDRESS TO PATCH
	HMODULE hModules[1024];
	DWORD needed;
	if (EnumProcessModules(hCurrProc,hModules,1024,&needed)) {
		for (int i = 0; i < (needed / sizeof(HMODULE)); i++ )
        {
            char szModName[1024];

            if ( GetModuleFileNameA( hModules[i], szModName, sizeof(szModName)))
            {
				if (StrStrA(szModName, "cpcspi.dll")) {
					writeAddr += (DWORD)hModules[i];
					printf("[+] Address in memory for patching is '%08X'.\n",writeAddr);
					break;
				}
            }
        }
	}

	
	/// !!!
	printf("[+] Now we patch process memory, patch size is '%i' bytes...",patchLen);
	VirtualProtectEx(hCurrProc, (void*)writeAddr, 2, PAGE_EXECUTE_READWRITE, &previous);
	WriteProcessMemory(hCurrProc, (void*)writeAddr, &patch, patchLen, NULL);
	printf("Ok\n");

	printf("[+] Now we export container '%s'...\n",SourceName);

	if(!CryptGetProvParam( 
	hProvSender, 
	92, 
	NULL, 
	&data_len, 
	0))
    {
		HandleError("Error computing buffer length");
    }

    oid = (BYTE *)malloc( data_len );
    if( !oid )
		HandleError("Out of memory.");


    if(!CryptGetProvParam( 
	hProvSender, 
	92, 
	oid, 
	&data_len, 
	0))
    {
		HandleError("Error during CryptGetProvParam");
    }


    if(!CryptSetProvParam(
	hProvResponder, 
	92, 
	oid, 
	0 ))
    {
		free( oid );
		HandleError("Error during CryptSetProvParam");
    }

    free( oid );

    data_len = 0;


    if(!CryptGetProvParam( 
	hProvSender, 
	93, 
	NULL, 
	&data_len, 
	0))
    {
		HandleError("Error computing buffer length");
    }

	/// SPECIFY PASSWORD FOR CONTAINER HERE
	if(!CryptSetProvParam( hProvSender,PP_SIGNATURE_PIN,(LPBYTE)Psdw,0))
	{
	    HandleError("Error during CryptSetProvParam");
	}

    oid = (BYTE *)malloc( data_len );
    if( !oid )
		HandleError("Out of memory");

    if(!CryptGetProvParam( 
	hProvSender, 
	93, 
	oid, 
	&data_len, 
	0))
    {
		free( oid );
		HandleError("Error during CryptGetProvParam");
    }

    if(!CryptSetProvParam(
	hProvResponder, 
	93, 
	oid, 
	0 ))
    {
		free( oid );
		HandleError("Error during CryptSetProvParam");
    }
    free( oid );


    if(!CryptGetUserKey( 
	hProvSender, 
	AT_KEYEXCHANGE, 
	&hSenderKey )) 
    {
		HandleError("Error during CryptGetUserKey private key");
    }		

	
    if(!CryptGenKey(
	hProvSender, 
	(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | 37), 
	CRYPT_EXPORTABLE, 
	&hSenderEphemKey)) 
    {
		HandleError("ERROR -- CryptGenKey");
    }
	
	
    if(!CryptGenKey(
	hProvResponder, 
	(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | 37), 
	CRYPT_EXPORTABLE | CRYPT_PREGEN,
	&hResponderEphemKey))
    {
		HandleError("ERROR -- CryptGenKey");
    }
	
	
    if(!CryptGetKeyParam( 
	hSenderEphemKey, 
	106, 
	NULL, 
	&dwBlobLen, 
	0))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob)
		HandleError("Out of memory");


    if(!CryptGetKeyParam( 
	hSenderEphemKey, 
	106, 
	pbKeyBlob, 
	&dwBlobLen, 
	0))
    {
		HandleError("Error during CryptGetProvParam");
    }

    if(!CryptSetKeyParam(
	hResponderEphemKey, 
	106, 
	pbKeyBlob, 
	0))
    {
		HandleError("Error during CryptSetProvParam");
    }

    free(pbKeyBlob);
    pbKeyBlob = NULL; 
    dwBlobLen = 0;


    if(!CryptSetKeyParam(
	hResponderEphemKey, 
	KP_X, 
	NULL, 
	0))
    {
		HandleError("Error during CryptSetKeyParam");
    }

    if(!CryptExportKey(
	hSenderEphemKey,
	0, 
	PUBLICKEYBLOB,
	0, 
	NULL,
	&dwBlobLen ))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob) 
		HandleError("Out of memory");

    if(!CryptExportKey(
	hSenderEphemKey,
	0, 
	PUBLICKEYBLOB,
	0, 
	pbKeyBlob,
	&dwBlobLen ))
    {
		HandleError("Error during CryptExportKey");
    }


    if(!CryptImportKey(
	hProvResponder, 
	pbKeyBlob, 
	dwBlobLen, 
	hResponderEphemKey, 
	0, 
	&hResponderAgreeKey))
    {
		HandleError("Error during CryptImportKey ephemeral key");
    }


    free(pbKeyBlob);
    pbKeyBlob = NULL; 
    dwBlobLen = 0;


    if(!CryptExportKey(
	hResponderEphemKey,
	0, 
	PUBLICKEYBLOB,
	0, 
	NULL,
	&dwBlobLen ))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob) 
		HandleError("Out of memory");

    if(!CryptExportKey(
	hResponderEphemKey,
	0, 
	PUBLICKEYBLOB,
	0, 
	pbKeyBlob,
	&dwBlobLen ))
    {
		HandleError("Error during CryptExportKey");
    }

 

    if(!CryptImportKey(
	hProvSender, 
	pbKeyBlob, 
	dwBlobLen, 
	hSenderEphemKey, 
	0, 
	&hSenderAgreeKey))
    {
		HandleError("Error during CryptImportKey ephemeral key");
    }


    free(pbKeyBlob);
    pbKeyBlob = NULL; 
    dwBlobLen = 0;


    if(!CryptSetKeyParam(
	hSenderAgreeKey,
	KP_ALGID, 
	(BYTE*)&cAlg,
	0 ))
    {
		HandleError("Error during CryptSetKeyParam agree key");
    }


    if(!CryptSetKeyParam(
	hResponderAgreeKey,
	KP_ALGID, 
	(BYTE*)&cAlg,
	0 ))
    {
		HandleError("Error during CryptSetKeyParam agree key");
    }
	

    if(!CryptExportKey(
	hSenderKey,
	hSenderAgreeKey, 
	PRIVATEKEYBLOB,
	0, 
	NULL,
	&dwBlobLen ))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob) 
		HandleError("Out of memory");

    if(!CryptExportKey(
	hSenderKey,
	hSenderAgreeKey, 
	PRIVATEKEYBLOB,
	0, 
	pbKeyBlob,
	&dwBlobLen ))
    {
		HandleError("Error during CryptExportKey");
    }



    if(!CryptImportKey(
	hProvResponder, 
	pbKeyBlob, 
	dwBlobLen, 
	hResponderAgreeKey, 
	0,
	&hResponderKey))
    {
		HandleError("Error during CryptImportKey private key");
    }


    free(pbKeyBlob);
    pbKeyBlob = NULL; 
    dwBlobLen = 0;



    if(!CryptGetKeyParam( 
	hSenderKey, 
	KP_CERTIFICATE, 
	NULL, 
	&dwBlobLen, 
	0))
    {
		HandleError("Error computing BLOB length");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);

    if(!pbKeyBlob)
    {
		HandleError("Out of memory");
    }


    if(!CryptGetKeyParam( 
	hSenderKey, 
	KP_CERTIFICATE, 
	pbKeyBlob, 
	&dwBlobLen, 
	0))
    {
		HandleError("Error during CryptGetProvParam");
    }

    if(!CryptSetKeyParam(
	hResponderKey, 
	KP_CERTIFICATE, 
	pbKeyBlob, 
	0))
    {
		HandleError("Error during CryptSetProvParam");
    }

	printf("[+] D0n3!!!\n");

    CleanUp();
    return 0;
}
Exemple #15
0
static BOOL
decodeSK( BOOL aes256, DWORD keylen, BYTE *keybuf )
{
    BYTE	buffer[ 1024 ];
    DWORD	i, size, length;

    struct skb
    {
	PUBLICKEYSTRUC	hdr;
	ALG_ID		algId;
	BYTE		key[1];
    }		*expKey = (struct skb *)buffer;

    struct ptkb
    {
	PUBLICKEYSTRUC	hdr;
	DWORD		keysize;
	BYTE		key[1];
    }		*txtKey = (struct ptkb *)buffer;

    length = (expKey->key - buffer) + keylen;

    if ( length > sizeof( buffer ) )
    {
	fprintf( stderr, "CryptImportKey() requires %d bytes\n", length );
	return( FALSE );
    }

    expKey->hdr.bType = SIMPLEBLOB;
    expKey->hdr.bVersion = CUR_BLOB_VERSION;
    expKey->hdr.reserved = 0;
    expKey->hdr.aiKeyAlg = aes256 ? SessKey256 : SessKey128;
    expKey->algId = XchgKeyType;

    /*
    ** NOTE: it appears that the encoded key is byte swapped compared
    ** to external standards.  There is a cryptic reference to a
    ** ReverseMemCopy() function in the RSA/SChannel server master
    ** key creation example.  Also, the internal RSA modulus is
    ** byte swapped compared to the X509 encoding.  This swap is
    ** required to interoperate with JavaSSE.
    */
    for( i = 0; i < keylen; i++ )
	expKey->key[i] = keybuf[ keylen - i - 1 ];

    if ( ! CryptImportKey( provider, (BYTE *)expKey, length, xchgKey, CRYPT_EXPORTABLE, &sessKey ) )
    {
	fprintf( stderr, "CryptImportKey() failed: 0x%x\n", GetLastError() );
	return( FALSE );
    }

    if ( ! CryptSetKeyParam( sessKey, KP_MODE, (BYTE *)&sessKeyMode, 0 ) )
    {
	fprintf( stderr, "CryptSetKeyParam() MODE failed: 0x%x\n", GetLastError() );
	return( 0 );
    }

    if ( ! CryptSetKeyParam( sessKey, KP_PADDING, (BYTE *)&sessKeyPadding, 0 ) )
    {
	fprintf( stderr, "CryptSetKeyParam() PADDING failed: 0x%x\n", GetLastError() );
	return( 0 );
    }

    if ( sessKeyMode == CRYPT_MODE_CBC )
    {
	size = sizeof( length );

	if ( ! CryptGetKeyParam( sessKey, KP_BLOCKLEN, (BYTE *)&length, &size, 0 ) )
	{
	    fprintf( stderr, "CryptGetKeyParam() BLOCKLEN failed: 0x%x\n", GetLastError() );
	    exit( 1 );
        }

	length /= 8;	/* Bits -> bytes */
	for( i = 0; i < length; i++ )  buffer[i] = 0;
	
	if ( ! CryptSetKeyParam( sessKey, KP_IV, buffer, 0 ) )
	{
	    fprintf( stderr, "CryptSetKeyParam() PADDING failed: 0x%x\n", GetLastError() );
	    return( 0 );
	}
    }

    if ( verbose )
    {
	if ( ! CryptExportKey( sessKey, 0, PLAINTEXTKEYBLOB, 0, NULL, &size ) )
	{
	    fprintf( stderr, "CryptExportKey() [1] failed: 0x%x\n", GetLastError() );
	    return( FALSE );
	}

	if ( size > sizeof( buffer ) )
	{
	    fprintf( stderr, "CryptExportKey() requires %d bytes\n", size );
	    return( FALSE );
	}

	length = sizeof( buffer );

	if ( ! CryptExportKey( sessKey, 0, PLAINTEXTKEYBLOB, 0, (BYTE *)txtKey, &length ) )
	{
	    fprintf( stderr, "CryptExportKey() [2] failed: 0x%x\n", GetLastError() );
	    return( FALSE );
	}

	printf( "Sess Key: \n" );
	hexDump( txtKey->keysize, txtKey->key );
	keyInfo( sessKey );
    }

    return( TRUE );
}
Exemple #16
0
BOOL ImportPlainSessionBlob(HCRYPTPROV hProv,
                            HCRYPTKEY hPrivateKey,
                            ALG_ID dwAlgId,
                            LPBYTE pbKeyMaterial ,
                            DWORD dwKeyMaterial ,
                            HCRYPTKEY *hSessionKey)
{
   BOOL fResult;   
   BOOL fReturn = FALSE;
   BOOL fFound = FALSE;
   LPBYTE pbSessionBlob = NULL;
   DWORD dwSessionBlob, dwSize, n;
   DWORD dwPublicKeySize;
   DWORD dwProvSessionKeySize;
   ALG_ID dwPrivKeyAlg;
   LPBYTE pbPtr; 
   DWORD dwFlags = CRYPT_FIRST;
   PROV_ENUMALGS_EX ProvEnum;
   HCRYPTKEY hTempKey = 0;

   __try
   {
      // Double check to see if this provider supports this algorithm
      // and key size
      do
      {        
         dwSize = sizeof(ProvEnum);
         fResult = CryptGetProvParam(hProv, PP_ENUMALGS_EX, (LPBYTE)&ProvEnum,
                                     &dwSize, dwFlags);
         if (!fResult) break;

         dwFlags = 0;

         if (ProvEnum.aiAlgid == dwAlgId) fFound = TRUE;
                                     
      } while (!fFound);

      if (!fFound) __leave;

      // We have to get the key size(including padding)
      // from an HCRYPTKEY handle.  PP_ENUMALGS_EX contains
      // the key size without the padding so we can't use it.
      fResult = CryptGenKey(hProv, dwAlgId, 0, &hTempKey);
      if (!fResult) __leave;
      
      dwSize = sizeof(DWORD);
      fResult = CryptGetKeyParam(hTempKey, KP_KEYLEN, (LPBYTE)&dwProvSessionKeySize,
                                 &dwSize, 0);
      if (!fResult) __leave;      
      CryptDestroyKey(hTempKey);
      hTempKey = 0;

      // Our key is too big, leave
      if ((dwKeyMaterial * 8) > dwProvSessionKeySize) __leave;

      // Get private key's algorithm
      dwSize = sizeof(ALG_ID);
      fResult = CryptGetKeyParam(hPrivateKey, KP_ALGID, (LPBYTE)&dwPrivKeyAlg, &dwSize, 0);
      if (!fResult) __leave;

      // Get private key's length in bits
      dwSize = sizeof(DWORD);
      fResult = CryptGetKeyParam(hPrivateKey, KP_KEYLEN, (LPBYTE)&dwPublicKeySize, &dwSize, 0);
      if (!fResult) __leave;

      // calculate Simple blob's length
      dwSessionBlob = (dwPublicKeySize/8) + sizeof(ALG_ID) + sizeof(BLOBHEADER);

      // allocate simple blob buffer
      pbSessionBlob = (LPBYTE)LocalAlloc(LPTR, dwSessionBlob);
      if (!pbSessionBlob) __leave;

      pbPtr = pbSessionBlob;

      // SIMPLEBLOB Format is documented in SDK
      // Copy header to buffer
      ((BLOBHEADER *)pbPtr)->bType = SIMPLEBLOB;
      ((BLOBHEADER *)pbPtr)->bVersion = 2;
      ((BLOBHEADER *)pbPtr)->reserved = 0;
      ((BLOBHEADER *)pbPtr)->aiKeyAlg = dwAlgId;
      pbPtr += sizeof(BLOBHEADER);

      // Copy private key algorithm to buffer
      *((DWORD *)pbPtr) = dwPrivKeyAlg;
      pbPtr += sizeof(ALG_ID);

      // Place the key material in reverse order
      for (n = 0; n < dwKeyMaterial; n++)
      {
         pbPtr[n] = pbKeyMaterial[dwKeyMaterial-n-1];
      }
     
      // 3 is for the first reserved byte after the key material + the 2 reserved bytes at the end.
      dwSize = dwSessionBlob - (sizeof(ALG_ID) + sizeof(BLOBHEADER) + dwKeyMaterial + 3);
      pbPtr += (dwKeyMaterial+1);

      // Generate random data for the rest of the buffer
      // (except that last two bytes)
      fResult = CryptGenRandom(hProv, dwSize, pbPtr);
      if (!fResult) __leave;

      for (n = 0; n < dwSize; n++)
      {
         if (pbPtr[n] == 0) pbPtr[n] = 1;
      }

      pbSessionBlob[dwSessionBlob - 2] = 2;

      fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob, 
                               hPrivateKey, CRYPT_EXPORTABLE, hSessionKey);
      if (!fResult) __leave;

      fReturn = TRUE;           
   }
   __finally
   {
      if (hTempKey) CryptDestroyKey(hTempKey);
      if (pbSessionBlob) LocalFree(pbSessionBlob);
   }
   
   return fReturn;
}
Exemple #17
0
int testSign(const char *containerNumber)
{
   char              provName[PROVIDER_BUFFER_SIZE];
   char              contName[CONTAINER_BUFFER_SIZE];
   DWORD             dwKeyUsage;
   HCRYPTPROV        hProv = 0;
   HCRYPTKEY         hKey;
   HCRYPTHASH        hHash;
   BYTE              pbData[200];
   BYTE              sig[512];
   DWORD             siglen;
   DWORD             dwAlgId;
   BYTE              data[500];
   DWORD             dwDataLen;
   long              err;
   int               errors = 0, count = 0;

   printf("\n*** Testing signatures ***\n");

   /* Get the provider name, container name and keyusage (SIGN or KEYEX) */
   if (listMyCerts(containerNumber, provName, contName, &dwKeyUsage))
       return 1;
   if (dwKeyUsage == -1) {
       printf("Container %d not present, exiting\n", atoi(containerNumber));
       return 1;
   }

   /* Acquire the provider handle */
   if(!CryptAcquireContext(&hProv, contName, provName, PROV_RSA_FULL, 0)) {
       err = GetLastError();
       printf("ERR: CryptAcquireContext: %s (0x%0x)\n", e2str(err), err);
       return 1;
   }

   // Done by Office2007
   if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey))
   {
       err = GetLastError();
       printf("ERR: CryptUserKey: %s (0x%0x)\n", e2str(err), err);
       errors++;
       goto done;
   }

   // Init hash
   if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) {
       err = GetLastError();
       printf("ERR: CryptCreateHash: %s (0x%0x)\n", e2str(err), err);
       errors++;
       goto done;
   }

   // Done by Office2007
   dwDataLen = sizeof(dwAlgId);
   if (!CryptGetKeyParam(hKey, KP_ALGID, (BYTE *) &dwAlgId, &dwDataLen, 0)) {
       err = GetLastError();
       printf("ERR: CryptGetKeyParam: %s (0x%0x)\n", e2str(err), err);
       errors++;
       goto done;
   }
   if (dwAlgId != CALG_RSA_KEYX) {
       printf("ERR: CryptGetKeyParam() should return CALG_RSA_KEYX instead of 0x%0x\n", dwAlgId);
       errors++;
   }

   // Done by Office2007
   if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen)) {
       err = GetLastError();
       printf("ERR: CryptExportKey: %s (0x%0x)\n", e2str(err), err);
       errors++;
       goto done;
   }
   if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, data, &dwDataLen)) {
       err = GetLastError();
       printf("ERR: CryptExportKey: %s (0x%0x)\n", e2str(err), err);
       errors++;
       goto done;
   }

   memset(pbData, 0x31, sizeof(pbData));

   // Hash data -- first part
   if (!CryptHashData(hHash, pbData, 50, 0)) {
       err = GetLastError();
       printf("ERR: CryptHashData(1): %s (0x%0x)\n", e2str(err), err);
       errors++;
       goto done;
   }

   // Hash data -- second part
   if (!CryptHashData(hHash, pbData + 50, sizeof(pbData) - 50, 0)) {
       err = GetLastError();
       printf("ERR: CryptHashData(1): %s (0x%0x)\n", e2str(err), err);
       errors++;
       goto done;
   }

   // Sign hash (get length)
   siglen = 0;
   if (!CryptSignHash(hHash, dwKeyUsage, NULL, 0, NULL, &siglen)) {
       err = GetLastError();
       printf("ERR: CryptSignHash(HP_HASHSIZE): %s (0x%0x)\n", e2str(err), err);
       errors++;
       goto done;
   }

   // Sign hash
   if (!CryptSignHash(hHash, dwKeyUsage, NULL, 0, sig, &siglen)) {
       err = GetLastError();
       printf("ERR: CryptSignHash(): %s (0x%0x)\n", e2str(err), err);
       errors++;
       goto done;
   }

   // Destroy hash
   if (!CryptDestroyHash(hHash)) {
       err = GetLastError();
       printf("ERR: CryptDestroyHash(): %s (0x%0x)\n", e2str(err), err);
       errors++;
   }

   // Done by Office2007
   if (!CryptDestroyKey(hKey)) {
       err = GetLastError();
       printf("ERR: CryptDestroyKey(): %s (0x%0x)\n", e2str(err), err);
       errors++;
   }

done:
   /* Release the provider handle */
   if(!CryptReleaseContext(hProv, 0)) {
       err = GetLastError();
       printf("ERR: CryptReleaseContext(): %s (0x%0x)\n", e2str(err), err);
       errors++;
   }

   printf("Done, %d error(s)\n\n", errors);

   return errors;
}
void mod_mimikatz_crypto::listAndOrExportCertificates(vector<wstring> * arguments, bool exportCert)
{
	wstring monEmplacement = L"CERT_SYSTEM_STORE_CURRENT_USER";
	wstring monStore = L"My";

	if(arguments->size() == 1)
	{
		monEmplacement = arguments->front();
	}
	else if(arguments->size() == 2)
	{
		monEmplacement = arguments->front();
		monStore = arguments->back();
	}
	
	(*outputStream) << L"Emplacement : \'" << monEmplacement << L'\'';

	DWORD systemStore;
	if(mod_crypto::getSystemStoreFromString(monEmplacement, &systemStore))
	{
		(*outputStream) << L"\\" << monStore << endl;
		if(HCERTSTORE hCertificateStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, NULL, NULL, systemStore | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, monStore.c_str()))
		{
			DWORD i;
			PCCERT_CONTEXT pCertContext;
			for (i = 0, pCertContext = CertEnumCertificatesInStore(hCertificateStore, NULL); pCertContext != NULL; pCertContext = CertEnumCertificatesInStore(hCertificateStore, pCertContext), i++)
			{
				wstring * certName = new wstring();
				bool reussite = false;

				if(!mod_crypto::getCertNameFromCertCTX(pCertContext, certName))
					certName->assign(L"[empty]");

				(*outputStream) << L"\t - " << *certName << endl;;
				sanitizeFileName(certName);

				wstringstream monBuff;
				monBuff << monEmplacement << L'_' << monStore << L'_' << i << L'_' << *certName << L'.';
										
				mod_crypto::KIWI_KEY_PROV_INFO keyProvInfo;
				if(mod_crypto::getKiwiKeyProvInfo(pCertContext, &keyProvInfo))
				{
					(*outputStream) << L"\t\tContainer Clé : " << keyProvInfo.pwszContainerName << endl;
					(*outputStream) << L"\t\tProvider      : " << keyProvInfo.pwszProvName << endl;
						
					HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv = NULL;
					DWORD keySpec = 0;
					BOOL aFermer = false;
						
					if(CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG /* CRYPT_ACQUIRE_SILENT_FLAG NULL */, NULL, &monProv, &keySpec, &aFermer))
					{
						(*outputStream) << L"\t\tType          : " << mod_crypto::KeyTypeToString(keySpec) << endl;
							
						DWORD size = 0;
						bool exportable = false;

						if(keySpec == CERT_NCRYPT_KEY_SPEC)
						{
							if(mod_cryptong::isNcrypt)
							{
								reussite = mod_cryptong::getKeySize(&monProv, &size);
								reussite &=mod_cryptong::isKeyExportable(&monProv, &exportable);

								if(aFermer)
								{
									mod_cryptong::NCryptFreeObject(monProv);
								}
							}
							else (*outputStream) << L"\t\t\tErreur : Clé de type nCrypt, sans nCrypt ?" << endl;
						}
						else
						{
							DWORD tailleEcrite = 0;
							DWORD exportability;

							HCRYPTKEY maCle = NULL;
							if(reussite = (CryptGetUserKey(monProv, keySpec, &maCle) != 0))
							{
								tailleEcrite = sizeof(DWORD);
								reussite = (CryptGetKeyParam(maCle, KP_KEYLEN, reinterpret_cast<BYTE *>(&size), &tailleEcrite, NULL) != 0);
								tailleEcrite = sizeof(DWORD);
								reussite &= (CryptGetKeyParam(maCle, KP_PERMISSIONS, reinterpret_cast<BYTE *>(&exportability), &tailleEcrite, NULL) != 0);
								exportable = (exportability & CRYPT_EXPORT) != 0;
							}

							if(aFermer)
							{
								CryptReleaseContext(monProv, 0);
							}
						}
						if(reussite)
						{
							(*outputStream) << L"\t\tExportabilité : " << (exportable ? L"OUI" : L"NON") << endl;
							(*outputStream) << L"\t\tTaille clé    : " << size << endl;
						}

						if(exportCert)
						{
							wstring PFXFile = monBuff.str();
							PFXFile.append(L"pfx");

							reussite = mod_crypto::CertCTXtoPFX(pCertContext, PFXFile, L"mimikatz");

							(*outputStream) << L"\t\tExport privé dans  \'" << PFXFile << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
							if(!reussite)
							{
								(*outputStream) << L"\t\t\t" << mod_system::getWinError() << endl;
							}
						}
					}
					else (*outputStream) << L"CryptAcquireCertificatePrivateKey : " << mod_system::getWinError() << endl;
				}

				if(exportCert)
				{
					wstring DERFile = monBuff.str();
					DERFile.append(L"der");
						
					reussite = mod_crypto::CertCTXtoDER(pCertContext, DERFile);
						
					(*outputStream) << L"\t\tExport public dans \'" << DERFile << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
					if(!reussite)
					{
						(*outputStream) << L"\t\t\t" << mod_system::getWinError() << endl;
					}
				}
				delete certName;
			}
			CertCloseStore(hCertificateStore, CERT_CLOSE_STORE_FORCE_FLAG);
		}
		else (*outputStream) << L"CertOpenStore : " << mod_system::getWinError() << endl;
	}
	else (*outputStream) << L" introuvable !" << endl;
}