使用openssl进行PKCS11密钥包装

时间:2014-03-26 14:04:37

标签: encryption openssl pkcs#11

我想使用C_WrapKey()使用由CreateObject加载的公钥在智能卡硬件上执行密钥换行操作。结果我收回了一个加密的字节数组。是否可以使用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字节。我想这是关于填充但不确定。

1 个答案:

答案 0 :(得分:2)

回答您的具体情况:

RFC3447表示RSAES-PKCS1-v1_5加密方案可以对长度达k-11个八位字节的消息进行操作(k是RSA模数的八位字节长度),因此无法使用128位RSA密钥加密192bit 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. &#34; des.key&#34;中存储的内容/密钥完全相同和&#34; unwrapped.key&#34;文件。这表明成功展开。

  7. 或者使用OpenSSL用RSA公钥包装DES3密钥:

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