OpenSSL:如何使用 p、q 和 e 创建 RSA 结构
OpenSSL: How to create RSA structure with p, q and e
是否有publicAPI通过指定p、q[=23=的值来创建RSA结构] 和 e?
我发现 Crypt-OpenSSL-RSA/RSA.xs 正在做我想做的事。
new_key_from_parameters
Given Crypt::OpenSSL::Bignum objects for n, e, and optionally d, p, and q, where p and q are the prime factors of n, e is the public exponent and d is the private exponent, create a new Crypt::OpenSSL::RSA object using these values.
但另一方面
rsa section in the OpenSSL manual
说:
applications should generally avoid using RSA structure elements directly and instead use API functions to query or modify keys
此时关于“使用 API”的说法是有抱负的。 RSA 模块是 OpenSSL 中最古老的模块之一
并且可以追溯到 SSLeay 和 Eric 关心其他事情而不是信息隐藏的时间。较新的模块
像 ECC SHA AES EVP,甚至像 BN BIO SSL 这样经过一些改造的,有 APIs 几乎总是保持不透明,
但 RSA 没有。现在这个项目实际上有多个开发人员,一些旧东西可能会被清理掉。
从语义上讲,您的组合不一致。用作 public 键的 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 又名 https://www.rfc-editor.org/rfc/rfc3447,一旦您拥有正确的 BN
值,现在只需将它们填充到 rsa->whatever
中。
Openssl 不提供 API 通过 p、q 生成密钥,但可以根据数学创建密钥...
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;
}
是否有publicAPI通过指定p、q[=23=的值来创建RSA结构] 和 e?
我发现 Crypt-OpenSSL-RSA/RSA.xs 正在做我想做的事。
new_key_from_parametersGiven Crypt::OpenSSL::Bignum objects for n, e, and optionally d, p, and q, where p and q are the prime factors of n, e is the public exponent and d is the private exponent, create a new Crypt::OpenSSL::RSA object using these values.
但另一方面 rsa section in the OpenSSL manual 说:
applications should generally avoid using RSA structure elements directly and instead use API functions to query or modify keys
此时关于“使用 API”的说法是有抱负的。 RSA 模块是 OpenSSL 中最古老的模块之一 并且可以追溯到 SSLeay 和 Eric 关心其他事情而不是信息隐藏的时间。较新的模块 像 ECC SHA AES EVP,甚至像 BN BIO SSL 这样经过一些改造的,有 APIs 几乎总是保持不透明, 但 RSA 没有。现在这个项目实际上有多个开发人员,一些旧东西可能会被清理掉。
从语义上讲,您的组合不一致。用作 public 键的 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 又名 https://www.rfc-editor.org/rfc/rfc3447,一旦您拥有正确的 BN
值,现在只需将它们填充到 rsa->whatever
中。
Openssl 不提供 API 通过 p、q 生成密钥,但可以根据数学创建密钥...
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;
}