OpenSSL:如何使用p,q和e创建RSA结构

时间:2015-10-13 11:43:59

标签: c openssl cryptography rsa private-key

是否有公共API通过指定 p q e 的值来创建RSA结构?

我发现Crypt-OpenSSL-RSA/RSA.xs正在做我想做的事。

  new_key_from_parameters      

给定n,e和可选的d,p和q的Crypt :: OpenSSL :: Bignum对象,其中p和q是n的主要因子,e是公共指数,d是私有指数,创建使用这些值的新Crypt :: OpenSSL :: RSA对象。

但是另一方面呢 rsa section in the OpenSSL manual 表示:

  

应用程序通常应该避免直接使用RSA结构元素,而是使用API​​函数来查询或修改密钥

2 个答案:

答案 0 :(得分:2)

关于"使用API​​"在这个时候是有抱负的。 RSA模块是OpenSSL中最古老的模块之一 和日期到SSLeay和Eric关心其他事情而不是信息隐藏。较新的模块 像ECC SHA AES EVP,甚至像BN BIO SSL这样的重做工具,都有几乎总是不透明的API, 但RSA没有。既然项目实际上有开发人员复数,那么这些旧东西中的一些可能会得到清理。

从语义上讲,你的组合是不一致的。用作公钥的RSA结构必须具有n和e,并且不应具有p q或任何其他私有信息; 用作私钥的一个必须有n d p q dp dq qinv并且可能是e。 (e不用于privatekey 操作, 但是需要检查密钥对或将其写出来或将其读回。)如果你真的有p q e,你必须计算n, 如果你想要一个私钥,你还必须计算d(然后)dp dq qinv。请参阅PKCS#1 aka http://tools.ietf.org/html/rfc3447,如果您现在拥有正确的BN值,请将其填入rsa->whatever

答案 1 :(得分:1)

Openssl不提供通过p,q生成密钥的API,但是可以基于数学创建一个...

 static int rsa_keygen_self(RSA *rsa, int bits)
      {
      BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
      BIGNUM local_r0,local_d,local_p;
      BIGNUM *pr0,*d,*p;
      int bitsp,bitsq,ok= -1,n=0;
      BN_CTX *ctx=NULL;

      ctx=BN_CTX_new();
      if (ctx == NULL) goto err;
      BN_CTX_start(ctx);
      r0 = BN_CTX_get(ctx);
      r1 = BN_CTX_get(ctx);
      r2 = BN_CTX_get(ctx);
      r3 = BN_CTX_get(ctx);
      if (r3 == NULL) goto err;

      bitsp=(bits+1)/2;
      bitsq=bits-bitsp;

      /* We need the RSA components non-NULL */
      if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
      if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
      if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
      if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
      if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
      if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
      if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
      if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;
 //p,q,e all from out side when creating RSA structure.




      /* calculate n */
      if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;

      /* calculate d */
      if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;    /* p-1 */
      if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;    /* q-1 */
      if (!BN_mul(r0,r1,r2,ctx)) goto err;    /* (p-1)(q-1) */
      if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
          {
            pr0 = &local_r0;
            BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
          }
      else
        pr0 = r0;
      if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err;   /* d */

      /* set up d for correct BN_FLG_CONSTTIME flag */
      if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
          {
          d = &local_d;
          BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
          }
      else
          d = rsa->d;

      /* calculate d mod (p-1) */
      if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;

      /* calculate d mod (q-1) */
      if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;

      /* calculate inverse of q mod p */
      if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
          {
          p = &local_p;
          BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
          }
      else
          p = rsa->p;
      if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;

      ok=1;
  err:
      if (ok == -1)
          {
          //RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
          ok=0;
          }
      if (ctx != NULL)
          {
          BN_CTX_end(ctx);
          BN_CTX_free(ctx);
          }

      return ok;
      }