Encryption 使用openssl的PKCS11密钥包装

Encryption 使用openssl的PKCS11密钥包装,encryption,openssl,pkcs#11,Encryption,Openssl,Pkcs#11,我正在尝试使用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 Publ

我正在尝试使用
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字节。我想是关于填充,但不确定。

回答您的具体情况:

表示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将DES3密钥与RSA密钥包装/展开。PKCS#11库使用的机制CKM#U RSA#U PKCS标识了OpenSSL完全支持的RSAES-PKCS1-v1#5加密方案(RSA encryption with PKCS#1 v1.5 padding)

您可以使用命令行OpenSSL工具和几行使用PKCS#11库的代码轻松检查我的答案是否正确:

  • 生成RSA密钥对:

    openssl genrsa -out private.key 2048
    
    openssl rsa -in private.key -pubout -out public.key
    
  • 从生成的RSA密钥对中提取RSA公钥:

    openssl genrsa -out private.key 2048
    
    openssl rsa -in private.key -pubout -out public.key
    
  • 从RSA公钥中提取模和指数:

    openssl rsa -in public.key -pubin -text
    
    openssl rsautl -encrypt -pkcs -pubin -inkey public.key -in unwrapped.key -out wrapped2.key
    
  • 将RSA公钥导入PKCS#11令牌,生成DES3密钥,用RSA公钥包装DES3密钥并保存结果(代码用C#编写):

    使用(Pkcs11 Pkcs11=new Pkcs11(“siecap11.dll”,false))
    {
    //查找存在令牌的第一个插槽
    Slot Slot=pkcs11.GetSlotList(true)[0];
    //开放RW会话
    使用(会话=slot.OpenSession(false))
    {
    //以普通用户身份登录
    session.Login(CKU.CKU_用户,“11111111”);
    //定义RSA公钥的属性
    List publicKeyAttributes=新列表();
    Add(新的ObjectAttribute(CKA.CKA_类,CKO.CKO_公钥));
    Add(新的ObjectAttribute(CKA.CKA_KEY_TYPE,CKK.CKK_RSA));
    Add(新的ObjectAttribute(CKA.CKA_标记,true));
    Add(新的ObjectAttribute(CKA.CKA_PRIVATE,false));
    Add(新的ObjectAttribute(CKA.CKA_标签,“WrapTest”);
    Add(新的ObjectAttribute(CKA.CKA_ID,ConvertUtils.HexStringToBytes(“00010203040506070809”));
    Add(新的ObjectAttribute(CKA.CKA_ENCRYPT,true));
    Add(新的ObjectAttribute(CKA.CKA_VERIFY,true));
    Add(新的ObjectAttribute(CKA.CKA\u VERIFY\u RECOVER,true));
    Add(新的ObjectAttribute(CKA.CKA_WRAP,true));
    //使用从RSA公钥中提取的模
    添加(新的ObjectAttribute(CKA.CKA_模数,ConvertUtils.hextStringToBytes("3.4 4 4 4 4 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8五,84B597FCE913CD586DA5E854B8264E708F0E52DE82E37F838D7106C876B9750946AF38D44EE4FF8F984E168557A83814FA4C2ACA413A7CBC0249BF0B76A2CE1FF2AB9A43463BE8EDE6A4579A6D416F);
    //使用从RSA公钥中提取的指数
    Add(新的ObjectAttribute(CKA.CKA_PUBLIC_EXPONENT,ConvertUtils.HexStringToBytes(“010001”));
    //导入公钥
    ObjectHandle pubKey=session.CreateObject(publicKeyAttributes);
    //定义DES键的属性
    List desKeyAttributes=new List();
    Add(新的ObjectAttribute(CKA.CKA_类,CKO.CKO_密钥));
    添加(新的ObjectAttribute(CKA.CKA_KEY_TYPE,CKK.CKK_DES3));
    Add(新的ObjectAttribute(CKA.CKA_ENCRYPT,true));
    Add(新的ObjectAttribute(CKA.CKA_DECRYPT,true));
    Add(新的ObjectAttribute(CKA.CKA_,true));
    Add(新的ObjectAttribute(CKA.CKA_可提取,true));
    //生成DES密钥
    ObjectHandle desKey=session.GenerateKey(新机制(CKM.CKM_DES3_KEY_GEN),desKeyAttributes);
    //读取DES键的值
    desKeyAttributes=session.GetAttributeValue(desKey,new List(){CKA.CKA_VALUE});
    字节[]desKeyValue=desKeyAttributes[0]。GetValueAsByteArray();
    System.IO.File.writealBytes(@“des.key”,desKeyValue);
    //包裹键
    byte[]wrappedKey=session.WrapKey(新机制(CKM.CKM_RSA_PKCS),pubKey,desKey);
    System.IO.File.writealBytes(@“wrapped.key”,wrappedKey);
    销毁对象(pubKey);
    会话。销毁对象(desKey);
    session.Logout();
    }
    }
    
  • 使用RSA私钥展开DES3密钥:

    openssl rsautl -decrypt -pkcs -inkey private.key -in wrapped.key -out unwrapped.key
    
  • “des.key”和“unwrapped.key”文件中存储的内容/密钥完全相同。这表示已成功展开

  • 或者使用OpenSSL将DES3密钥包装为RSA公钥:

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

  • “是否可以使用openssl执行相同的操作”-我不相信这是可能的,因为openssl没有通过命令行工具公开密钥wrap算法。您还必须知道智能卡使用哪种wrap算法(openssl仅提供其中一种)。您使用C_WrapKey的机制是什么?