【问题标题】:OpenSSL: How to create RSA structure with p, q and eOpenSSL:如何使用 p、q 和 e 创建 RSA 结构
【发布时间】:2015-10-13 11:43:59
【问题描述】:

是否有公共 API 可以通过指定 pqe 的值来创建 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 函数来查询或修改密钥

【问题讨论】:

    标签: c openssl cryptography rsa private-key


    【解决方案1】:

    关于“使用 API”的声明在这个时候是有抱负的。 RSA 模块是 OpenSSL 中最古老的模块之一 并且可以追溯到 SSLeay 和 Eric 关心其他事情而不是信息隐藏的时候。较新的模块 像 ECC SHA AES EVP,甚至像 BN BIO SSL 这样经过重新设计的 API,其 API 几乎总是不透明, 但 RSA 没有。现在该项目实际上有多个开发人员,其中一些旧的东西可能会被清理掉。

    从语义上讲,您的组合不一致。用作公钥的RSA 结构必须有n 和e,并且不应该有p q 或任何其他私人信息; 一个用作私钥的必须有 n d p q dp dq qinv 并且可能有 e。 (e 不用于私钥操作, 但需要检查密钥对或将其写出或读回。)如果你真的有 p q e 你必须计算 n, 如果你想要一个私钥,你还必须计算 d (then) dp dq qinv。请参阅 PKCS#1 aka https://www.rfc-editor.org/rfc/rfc3447,一旦您拥有正确的 BN 值,现在只需将它们填充到 rsa->whatever 中。

    【讨论】:

      【解决方案2】:

      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;
            }
      

      【讨论】:

      • 代码好像来自openssl的crypto/rsa/rsa_gen.c。
      猜你喜欢
      • 2012-08-07
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 2014-06-10
      • 2011-12-11
      • 2023-03-15
      • 2010-11-24
      相关资源
      最近更新 更多