是否有公共API通过指定 p , q 和 e 的值来创建RSA结构?
我发现Crypt-OpenSSL-RSA/RSA.xs正在做我想做的事。
new_key_from_parameters但是另一方面呢 rsa section in the OpenSSL manual 表示:给定n,e和可选的d,p和q的Crypt :: OpenSSL :: Bignum对象,其中p和q是n的主要因子,e是公共指数,d是私有指数,创建使用这些值的新Crypt :: OpenSSL :: RSA对象。
应用程序通常应该避免直接使用RSA结构元素,而是使用API函数来查询或修改密钥
答案 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;
}