2014-03-26 190 views
2

我正在使用C_WrapKey()和一個由CreateObject加載的公用密鑰在智能卡硬件上執行密鑰包裝操作。作爲結果,我找回了一個加密的字節數組。是否可以使用openssl執行相同的操作?PKCS11使用openssl的密鑰包裝

我嘗試使用opensal如下:

openssl rsautl -encrypt -in symkey.data -out symkey.enc -pubin rsaPub.der -keyform DER -pkcs 

symkey.data: 192 bits DES3 key 
rsaPub.der : 128 bit RSA Public key in DER format 

所得symkey.enc文件是大小爲128個字節,但從我的硬件結果始終是256個字節。我想這是關於填充,但不知道。

+0

「是否有可能使用OpenSSL的執行相同的操作」 - 因爲OpenSSL的不,我不相信它可能通過命令行工具公開密鑰包裝算法。您還必須知道智能卡使用哪種換行算法(OpenSSL僅提供其中的一種算法)。 – jww

+0

你使用什麼機制與C_WrapKey? – jariq

+0

這是CKM_RSA_PKCS。 – mll5

回答

2

爲了回答您的特定情況:

RFC3447說RSAES-PKCS1-v1_5中的加密方案可以在長度的消息多達K個操作 - 11個八位位組(k是RSA模量的八位位組的長度),所以您無法使用128位RSA密鑰來加密192位DES3密鑰。 OpenSSL最終會出現以下錯誤:

openssl rsautl -encrypt -in symkey.data -out symkey.enc -pubin -inkey rsaPub.der -keyform DER -pkcs 
RSA operation error 
7240:error:0406D06D:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size:.\crypto\rsa\rsa_pk1.c:151: 

您確定您提供了正確的信息在您的問題?

要回答與OpenSSL的密鑰包裝一般:

是的,它有可能與包裝使用OpenSSL RSA密鑰/解包DES3密鑰。您正在與PKCS#11庫一起使用的機制CKM_RSA_PKCS標識了OpenSSL完全支持的RSAES-PKCS1-v1_5加密方案(帶有PKCS#1 v1.5填充的RSA加密)。

可以輕鬆地檢查出我的回答是使用命令行的OpenSSL工具,並使用PKCS的幾行代碼正確#11庫:

  1. 生成RSA密鑰對

    openssl genrsa -out private.key 2048 
    
  2. 提取RSA從生成的RSA密鑰對的公鑰:

    openssl rsa -in private.key -pubout -out public.key 
    
  3. 提取係數和指數從RSA公鑰:

    openssl rsa -in public.key -pubin -text 
    
  4. 導入RSA公鑰到您的PKCS#11令牌,生成DES3鍵,包裝與RSA公鑰DES3密鑰並保存結果(代碼是用C#) :

    using (Pkcs11 pkcs11 = new Pkcs11("siecap11.dll", false)) 
    { 
        // Find first slot with token present 
        Slot slot = pkcs11.GetSlotList(true)[0]; 
    
        // Open RW session 
        using (Session session = slot.OpenSession(false)) 
        { 
         // Login as normal user 
         session.Login(CKU.CKU_USER, "11111111"); 
    
         // Define attributes of RSA public key 
         List<ObjectAttribute> publicKeyAttributes = new List<ObjectAttribute>(); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY)); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_RSA)); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true)); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false)); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, "WrapTest")); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ConvertUtils.HexStringToBytes("00010203040506070809"))); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true)); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY, true)); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY_RECOVER, true)); 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_WRAP, true)); 
         // Use modulus extracted from RSA public key 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_MODULUS, ConvertUtils.HexStringToBytes("c3968577a4f007485e77cdf20beca6a4dd200a3d9e478e14db66a4e40534b530c08b1f0604e7dc44e4171b85d84a550b189f94751d7cb048040a66440698f33d8f4634a3e5623a6e69b98563e622df187429738ea4c5e697f236d2d80792803cfc783670ce9697b380cf3603efca098b0db2eac3b48ff80161ea3dd00c7657f7366fc2bafa4ef617ee1a927eff71dcc3037df5ed09bd82dd976be3fd0d192b7d18aac71ff3d7b760946963786558584b597fce913cd586da5e854b8264e708f0e52de82e37f838d7106c876b9750946af38d44ee4ff8f984e168557a83814fa4c2acaca413a7cbc0249bf0b76a2ce1ff2ab9a43463c3be8ede6a4579a6d4168f"))); 
         // Use exponent extracted from RSA public key 
         publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PUBLIC_EXPONENT, ConvertUtils.HexStringToBytes("010001"))); 
    
         // Import public key 
         ObjectHandle pubKey = session.CreateObject(publicKeyAttributes); 
    
         // Define attributes of DES key 
         List<ObjectAttribute> desKeyAttributes = new List<ObjectAttribute>(); 
         desKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY)); 
         desKeyAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3)); 
         desKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true)); 
         desKeyAttributes.Add(new ObjectAttribute(CKA.CKA_DECRYPT, true)); 
         desKeyAttributes.Add(new ObjectAttribute(CKA.CKA_DERIVE, true)); 
         desKeyAttributes.Add(new ObjectAttribute(CKA.CKA_EXTRACTABLE, true)); 
    
         // Generate DES key 
         ObjectHandle desKey = session.GenerateKey(new Mechanism(CKM.CKM_DES3_KEY_GEN), desKeyAttributes); 
    
         // Read value of DES key 
         desKeyAttributes = session.GetAttributeValue(desKey, new List<CKA>() { CKA.CKA_VALUE }); 
         byte[] desKeyValue = desKeyAttributes[0].GetValueAsByteArray(); 
         System.IO.File.WriteAllBytes(@"des.key", desKeyValue); 
    
         // Wrap key 
         byte[] wrappedKey = session.WrapKey(new Mechanism(CKM.CKM_RSA_PKCS), pubKey, desKey); 
         System.IO.File.WriteAllBytes(@"wrapped.key", wrappedKey); 
    
         session.DestroyObject(pubKey); 
         session.DestroyObject(desKey); 
         session.Logout(); 
        } 
    } 
    
  5. 與RSA私鑰

    展開DES3鍵:

    openssl rsautl -decrypt -pkcs -inkey private.key -in wrapped.key -out unwrapped.key 
    
  6. 有存儲完全相同的內容/關鍵在「des.key」和「unwrapped.key」文件中。這表明成功解包。

  7. 或者使用OpenSSL包DES3密鑰與RSA公鑰:

    openssl rsautl -encrypt -pkcs -pubin -inkey public.key -in unwrapped.key -out wrapped2.key