2013-09-26 53 views
1

在我的C++程序中,我使用CryptoAPI創建了公鑰/私鑰對。通過PKCS獲取CryptoAPI公鑰#11

CryptGenKey(eTokenProv,ENCRYPT_ALGORITHM,CRYPT_EXPORTABLE,&k1) 

密鑰存儲在一個的eToken。 是否可以使用公鑰PKCS#11?先前創建的使用以下搜索模板搜索後發現私鑰:

CK_ATTRIBUTE private_search[] = { 
     {CKA_PRIVATE, CK_TRUE, sizeof(CK_BBOOL)} 
    }; 

如果我設置CKA_PRIVATE到CK_FALSE,我不能讓公共密鑰。我也嘗試過其他屬性。 有沒有辦法做到這一點?

編輯

由於owlstead建議,我試圖創建從一個對話期間建立(CAPI中的一個關鍵的模量和公共指數,或只是爲了本次測試啓動公共密鑰,在PKCS11)。我從一個私鑰這些緩衝器的模量和公共指數:

CK_BYTE modulus[128]; //if 1024bit 
CK_BYTE publicExponent[4]; //4 Byte, according to public key blob 

但是,當我嘗試用下面的指令鍵上創建一個新的公用:

CK_ATTRIBUTE publicKeyTemplate[] = { 
    {CKA_TOKEN, &yes, sizeof(true)}, 
    {CKA_WRAP, &yes, sizeof(true)}, 
    {CKA_ENCRYPT, &yes, sizeof(true)}, 
    {CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)}, 
    {CKA_MODULUS, &modulus, sizeof(modulus)}, 
    {CKA_PUBLIC_EXPONENT, &publicExponent, sizeof(publicExponent)} 

CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 }; 
rv = (*functions->C_GenerateKeyPair) (session, &mechanism, publicKeyTemplate, 6, privateKeyTemplate, 6, &hPublicKey, &hPrivateKey); 

我得到的錯誤「無效的模板「。問題是模數,因爲如果沒有它,我可以創建一個密鑰對。我使用功能C_GenerateKeyPair,但我只對公鑰感興趣。我省略了私人模板。 這裏有什麼問題?

回答

2

CKA_PRIVATE根本不表示私鑰。

當CKA_PRIVATE屬性爲真,用戶可能無法訪問對象,直到用戶 已被認證令牌

相反,你應該尋找爲CKA_CLASS這樣的屬性與價值CKO_PUBLIC_KEYCKO_PRIVATE_KEY,可能使用其他屬性來進一步過濾您的結果。

如果您找不到任何CKO_PUBLIC_KEY,那麼我認爲它不是在令牌中生成的(密鑰已導入,請檢查是否設置了CKA_LOCAL)。或者,它可能只被創建爲會話對象。最後它可能已被刪除。

請注意,RSA私鑰通常包含公開指數,所以您仍然可以僅使用私鑰對象(當然使用模數和公開指數)構造公鑰。

+0

好的,謝謝你的回答!我做了一些測試,發現:私鑰(即CKA_CLASS = CKO_PRIVATE_KEY)不是本地的 - 可能是因爲它是通過CAPI創建的;沒有找到CKO_PUBLIC_KEY鍵。所以,正如你所建議的那樣,爲了重新構建公鑰,我們可以從私鑰模板中獲得CKA_MODULUS和CKA_PUBLIC_EXPONENT。我會試試看! – andret8

+0

如果'CKA_LOCAL'沒有設置,那麼你可能想要再看看你的設置的安全性。如果私鑰在生成並保留在令牌中(如果密鑰管理方案不允許生成新密鑰,則可能用於加密備份除外),則它是最安全的。 –

+0

如果我通過PKCS#11創建私鑰,則CKA_LOCAL設置爲true。也許,如果它沒有設置,它取決於一個CryptoAPI設置..我會檢查它。關於公鑰,我編輯我的問題與其他細節..任何其他建議?非常感謝 – andret8

0

當設置一個指向CK_BYTE數組的指針時,刪除CK_ATTRIBUTE中的引用符號 - 在你的情況下模數

CK_ATTRIBUTE publicKeyTemplate[] = { 
    {CKA_TOKEN, &yes, sizeof(true)}, 
    {CKA_WRAP, &yes, sizeof(true)}, 
    {CKA_ENCRYPT, &yes, sizeof(true)}, 
    {CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)}, 
    {CKA_MODULUS, modulus, sizeof(modulus)}, 
    {CKA_PUBLIC_EXPONENT, &publicExponent, sizeof(publicExponent)} 

我沒有測試你的代碼,但我可以通過設置下面的模板,使以C_GetAttributeValue呼叫成功獲得CK_OBJECT_HANDLE模量(私鑰/公鑰):

CK_BYTE   modulus[128]; 
CK_ATTRIBUTE Modulus = { CKA_MODULUS, modulus, sizeof(modulus) }; 

if ((rv = (*p11FunctionList->C_GetAttributeValue)(hSession, hPrivKey /*hPubKey*/, &Modulus, 1)) == CKR_OK) 
{ 
    // do something with obtained modulus 
} 

生成公私密鑰對被如下產生:

CK_OBJECT_HANDLE hPrivKey, hPubKey; 
CK_BBOOL   bTrue = TRUE; 
CK_ULONG   mod_bits = 1024; 
CK_MECHANISM  GenMechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };   

CK_ATTRIBUTE  GenPubTemplate[] = { 
      { CKA_MODULUS_BITS, &mod_bits, sizeof(CK_ULONG) }, 
      { CKA_PUBLIC_EXPONENT, "\x01\x00\x01", 3 }, 
      { CKA_TOKEN, &bTrue, sizeof(CK_BBOOL) }, 
      { CKA_ID, (CK_CHAR_PTR)szKeyID, strlen(szKeyID) } }; // szKeyID is a const char * 

     CK_ATTRIBUTE   GenPrivTemplate[] = { 
      { CKA_TOKEN, &bTrue, sizeof(CK_BBOOL) }, 
      { CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL) }, 
      { CKA_SENSITIVE, &bTrue, sizeof(CK_BBOOL) }, 
      { CKA_ID, (CK_CHAR_PTR)szKeyID, strlen(szKeyID) } }; // szKeyID is a const char * 

// hSession is a CK_SESSION_HANDLE of an opened & logged in session 
if ((rv = (*p11FunctionList->C_GenerateKeyPair)(hSession, &GenMechanism, GenPubTemplate, 4, GenPrivTemplate, 4, &hPubKey, &hPrivKey)) == CKR_OK) 
{ 
    // Now get the modulus of a the private/public key as described above 
} 
0

雖然這已經回答了別人誰想要做到這一點,我們已經創建了一個基於PKCS#11 WR衝擊片雷管的CryptoAPI的,你可以在這裏找到:

https://github.com/PeculiarVentures/pvpkcs11

有了這個,你可以使用本地PKCS#11接口訪問存儲在CryptoAPI的以及證書的密鑰。