CryptEncodeObjectEx 函式 (wincrypt.h)

CryptEncodeObjectEx 函式會編碼 lpszStructType 參數值所指示之型別的結構。 此函式藉由支援具有CRYPT_ENCODE_ALLOC_FLAG值的記憶體配置,大幅改善 CryptEncodeObject 的效能。

語法

BOOL CryptEncodeObjectEx(
  [in]      DWORD              dwCertEncodingType,
  [in]      LPCSTR             lpszStructType,
  [in]      const void         *pvStructInfo,
  [in]      DWORD              dwFlags,
  [in]      PCRYPT_ENCODE_PARA pEncodePara,
  [out]     void               *pvEncoded,
  [in, out] DWORD              *pcbEncoded
);

參數

[in] dwCertEncodingType

用來編碼對象的憑證編碼類型和訊息編碼類型。 此參數可以是下列一或多個值的組合。

意義
PKCS_7_ASN_ENCODING
65536 (0x10000)
指定 PKCS 7 訊息編碼。
X509_ASN_ENCODING
1 (0x1)
指定 X.509 憑證編碼。

[in] lpszStructType

定義結構類型的 物件標識碼 (OID) 指標。 如果 lpszStructType 參數的高序單字為零,則低順序字組會指定指定結構類型的整數標識符。 否則,此參數是 Null 終止字串的指標,其中包含 OID 的字串表示。

如需對象標識符字串、其預先定義的常數和對應的結構的詳細資訊,請參閱 CryptEncodeObject 和 CryptDecodeObject 的常數

[in] pvStructInfo

要編碼之 結構的指標。 結構必須是 lpszStructType 所指定的類型。

[in] dwFlags

指定編碼的選項。 此參數可以是零或下列一或多個值的組合。

意義
CRYPT_ENCODE_ALLOC_FLAG
32768 (0x8000)
呼叫的編碼函式會為編碼的位元組配置記憶體。 pvEncoded 中會傳回配置位元組的指標。
CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG
131072 (0x20000)
此旗標適用於啟用 Unicode 字串值的 Punycode 編碼。 如需詳細資訊,請參閱<備註>。

Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支援此旗標。

CRYPT_UNICODE_NAME_ENCODE_DISABLE_CHECK_TYPE_FLAG
1073741824 (0x40000000)
當編碼X509_UNICODE_NAME、X509_UNICODE_NAME_VALUE或X509_UNICODE_ANY_STRING時,適用此旗標。 如果設定此旗標,則不會檢查字元,以判斷它們是否對指定的實值型別有效。
CRYPT_UNICODE_NAME_ENCODE_ENABLE_T61_UNICODE_FLAG
2147483648 (0x80000000)
當編碼X509_UNICODE_NAME時,適用此旗標。 如果已設定此旗標,且所有 Unicode 字元都是 <= 0xFF,則會選取CERT_RDN_T61_STRING,而不是CERT_RDN_UNICODE_STRING。
CRYPT_UNICODE_NAME_ENCODE_ENABLE_UTF8_UNICODE_FLAG
536870912 (0x20000000)
當編碼X509_UNICODE_NAME時,適用此旗標。 設定時,會選取CERT_RDN_UTF8_STRING,而不是CERT_RDN_UNICODE_STRING。
CRYPT_UNICODE_NAME_ENCODE_FORCE_UTF8_UNICODE_FLAG
268435456 (0x10000000)
當編碼X509_UNICODE_NAME時,適用此旗標。 設定時,會選取CERT_RDN_UTF8_STRING,而不是針對目錄字串類型選取CERT_RDN_PRINTABLE_STRING。 此外,此旗標會啟用CRYPT_UNICODE_NAME_ENCODE_ENABLE_UTF8_UNICODE_FLAG。

[in] pEncodePara

包含編碼資訊 之CRYPT_ENCODE_PARA 結構的指標。 此參數可以是 Null

如果 pEncodePara 或 pEncodeParapfnAlloc 成員為 NULL,則 LocalAlloc 會用於配置,而且必須呼叫 LocalFree 以釋放記憶體。

如果 pEncodeParapEncodeParapfnAlloc 成員不是 NULL,則會針對配置呼叫 pEncodePara 所指向之 CRYPT_ENCODE_PARA 結構的 pfnAlloc 成員所指向的函式。 必須呼叫 pEncodePara的 pfnFree 成員指向的函式,才能釋放記憶體。

[out] pvEncoded

要接收編碼結構的緩衝區指標。 這個緩衝區的大小是在 參數 中指定。 當指定的緩衝區不夠大而無法接收譯碼的結構時,函式會設定 ERROR_MORE_DATA 程序代碼,並將所需的緩衝區大小以位元組為單位儲存在 由ERROR_MORE_DATA coded 所指向的變數中。

此參數可以是 NULL ,可擷取緩衝區的大小以供記憶體配置之用。 如需詳細資訊,請參閱 擷取未知長度的數據

如果 dwFlags 包含 CRYPT_ENCODE_ALLOC_FLAG 旗標, pvEncoded 不是緩衝區的指標,而是緩衝區指標的位址。 因為記憶體配置在函式內,而且指標儲存在 pvEncoded 中, 所以 pvEncoded 不能是 NULL

[in, out] pcbEncoded

DWORD 變數的指標,其中包含 pvEncoded 參數所指向之緩衝區的大小,以位元組為單位。 當函式傳回時, 由 HTTPEncoded 參數指向的變數會包含儲存在緩衝區中已配置、編碼的位元元數目。

當 dwFlags 包含CRYPT_ENCODE_ALLOC_FLAG旗標時,則CRYPT_ENCODE_ALLOC_FLAG coded 是更新之 DWORD 值指標的位址。

注意 處理緩衝區中傳回的數據時,應用程式必須使用傳回的數據實際大小。 實際大小可能會稍微小於輸入中指定的緩衝區大小。 (輸入時,通常會指定足夠的緩衝區大小,以確保最大的可能輸出數據符合 buffer。) On 輸出中,此參數所指向的變數會更新,以反映複製到緩衝區的實際數據大小。
 

傳回值

如果成功或零,則傳回非零。

如需擴充的錯誤資訊,請呼叫 GetLastError。 下表顯示當 CryptEncodeObjectEx 失敗時可從 GetLastError 傳回的一些可能錯誤碼。

傳回碼 Description
CRYPT_E_BAD_ENCODE
編碼時發生錯誤。
ERROR_FILE_NOT_FOUND
找不到指定 dwCertEncodingTypelpszStructType 的編碼函式。
ERROR_MORE_DATA
如果 pvEncoded 參數指定的緩衝區不夠大,無法保存傳回的數據,函式會設定 ERROR_MORE_DATA 程式代碼,並將所需的緩衝區大小以位元組為單位儲存在 由coded 指向的變數中。
 

如果函式失敗, GetLastError 可能會傳回 抽象語法表示法 1 (ASN.1) 編碼/譯碼錯誤。 如需這些錯誤的相關信息,請參閱 ASN.1 編碼/譯碼傳回值

備註

使用慣用 CryptEncodeObjectEx 函式編碼密碼編譯物件時,會包含終止 的 NULL 字元。 譯碼時,使用慣用 的 CryptDecodeObjectEx 函式,不會保留終止 的 NULL 字元。

CryptEncodeObjectEx 會先尋找可安裝的擴充編碼函式。 如果找不到擴充編碼函式,則會找到舊的無xtended 可安裝函式。

當無法直接 編碼物件的 IA5String 時,您可以將 dwFlag 參數設定為 CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG 值,以指定 Punycode 編碼。 根據 lpszStructType 參數的值所指定的結構類型,設定CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG旗標會有不同的效果。

下列清單中的每個常數都有一個相關聯的結構類型,由 pvStructInfo 參數所指向。 直接或間接指向的結構具有 CERT_ALT_NAME_ENTRY 結構的參考。

  • X509_ALTERNATE_NAME
  • szOID_AUTHORITY_INFO_ACCESS
  • X509_AUTHORITY_INFO_ACCESS
  • X509_AUTHORITY_KEY_ID2
  • szOID_AUTHORITY_KEY_IDENTIFIER2
  • szOID_CRL_DIST_POINTS
  • X509_CRL_DIST_POINTS
  • szOID_CROSS_CERT_DIST_POINTS
  • X509_CROSS_CERT_DIST_POINTS
  • szOID_ISSUER_ALT_NAME
  • szOID_ISSUER_ALT_NAME2
  • szOID_ISSUING_DIST_POINT
  • X509_ISSUING_DIST_POINT
  • szOID_NAME_CONSTRAINTS
  • X509_NAME_CONSTRAINTS
  • szOID_NEXT_UPDATE_LOCATION
  • OCSP_REQUEST
  • zOID_SUBJECT_ALT_NAME
  • szOID_SUBJECT_ALT_NAME2
CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG旗標,與 CERT_ALT_NAME_ENTRY 結構之 dwAltNameChoice 成員的值一起使用,決定字串編碼的方式。
dwAltNameChoice 效果
CERT_ALT_NAME_DNS_NAME 如果主機名包含 ASCII 字元集以外的 Unicode 字元,則主機名會先以 Punycode 編碼,然後編碼為 IA5String 字串。
CERT_ALT_NAME_RFC822_NAME 如果電子郵件位址的主機名部分包含 ASCII 字元集以外的 Unicode 字元,則電子郵件地址的主機名部分會以 Punycode 編碼。 然後,產生的電子郵件地址會編碼為 IA5String 字串串。
CERT_ALT_NAME_URL 如果 URI 的伺服器主機名包含 ASCII 字元集以外的 Unicode 字元,則 URI 的主機名部分會以 Punycode 編碼。 然後會逸出結果 URI,然後 URL 會編碼為 IA5String 字串。
 

下列清單中的每個常數都有 pvStructInfo 參數所指向的相關聯結構類型。 直接或間接指向的結構具有 CERT_HASHED_URL 結構的參考。

  • szOID_BIOMETRIC_EXT
  • X509_BIOMETRIC_EXT
  • szOID_LOGOTYPE_EXT
  • X509_LOGOTYPE_EXT
編碼 CERT_HASHED_URL 結構值時,如果 URI 的伺服器主機名包含 ASCII 字元集以外的 Unicode 字元,且 已設定CRYPT_ENCODE_ENABLE_PUNYCODE_FLAG,URI 的主機名部分會以 Punycode 編碼。 然後會逸出結果 URI,然後 URL 會編碼為 IA5String 字串。

下列清單中的每個 X509_UNICODE_NAME 常數都有 pvStructInfo 參數所指向的相關聯結構類型。

  • X509_UNICODE_NAME
如果CERT_RDN_ATTR結構的 pszObjId 成員設定為 szOID_RSA_emailAddr且 Value 成員中的電子郵件位址包含 ASCII 字元集以外的 Unicode 字元,則電子郵件地址的主機名部分會以 Punycode 編碼。 然後,產生的電子郵件地址會編碼為 IA5String 字串串。

在所有情況下,主機名的 Punycode 編碼會以標籤為基礎執行。

範例

下列範例示範使用 CryptEncodeObjectEx 初始化和編碼X509_NAME結構。 如需包含此範例完整內容的範例,請參閱 範例 C 程式:ASN.1 編碼和譯碼

#include <windows.h>
#include <stdio.h>
#include <Wincrypt.h>
#pragma comment(lib, "crypt32.lib")


#define MY_TYPE (X509_ASN_ENCODING)

void main()
{

//#define moved

//--------------------------------------------------------------------
//   Declare and initialize local variables.

char *Cert_Sub_Name ="Test User Name";

//--------------------------------------------------------------------
// Initialize a single RDN structure.

CERT_RDN_ATTR rgNameAttr = 
{
   "2.5.4.3",                      // The OID
   CERT_RDN_PRINTABLE_STRING,      // Type of string
   (DWORD)strlen(Cert_Sub_Name)+1, // String length including
                                   //  the terminating null character
   (BYTE *)Cert_Sub_Name           // Pointer to the string 
};
//--------------------------------------------------------------------
// Declare and initialize a structure to include
// the array of RDN structures.

CERT_RDN rgRDN[] = 
{
   1,               // The number of elements in the array
   &rgNameAttr      // Pointer to the array
};

//--------------------------------------------------------------------
//  Declare and initialize a CERT_NAME_INFO 
//  structure that includes a CERT_RND.

CERT_NAME_INFO CertName = 
{
    1,          // The number of elements in the CERT_RND's array
    rgRDN
};

//--------------------------------------------------------------------
//  Declare additional variables.

DWORD cbEncoded;              // Variable to hold the
                              //  length of the encoded string
BYTE *pbEncoded;              // Variable to hold a pointer to the 
                              //  encoded buffer
//--------------------------------------------------------------------
// Call CrypteEncodeObjectEx to get 
// length to allocate for pbEncoded.

if( CryptEncodeObjectEx(
     MY_TYPE,        // The encoding/decoding type
     X509_NAME,    
     &CertName,
     0,                 
     NULL, 
     NULL,
     &cbEncoded))    // Fill in the length needed for
                     // the encoded buffer.
{
     printf("The number of bytes needed is %d \n",cbEncoded);
}
else
{
     printf("The first call to the function failed.\n");
     exit(1);
}

if( pbEncoded = (BYTE*)malloc(cbEncoded))
{
     printf("Memory for pvEncoded has been allocated.\n");
}
else
{
    printf("Memory allocation failed.\n");
    exit(1);
}

if(CryptEncodeObjectEx(
     MY_TYPE,
     X509_NAME,
     &CertName,
     0,
     NULL, 
     pbEncoded,
     &cbEncoded))
{
     printf("The structure has been encoded.\n");
}
else
{
     printf("Encoding failed.");
     exit(1);
}
// Free allocated memory when done.
// ...
if(pbEncoded)
{
    free(pbEncoded);
}


規格需求

需求
最低支援的用戶端 Windows XP [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 wincrypt.h
程式庫 Crypt32.lib
Dll Crypt32.dll

另請參閱

CryptDecodeObject

CryptDecodeObjectEx

CryptEncodeObject

物件編碼和譯碼函式