Chinese remainder algorithm

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Chinese remainder algorithm

Jan Bilek
Hi all,

I need to reconstruct public and private keys for data signing operation from p, q, dmp1, dmq1 and iqmp. When I fill values in as per below then OpenSSL complains about missing d.

    RSA* pkey = RSA_new();
    pkey->n = NULL;
    pkey->e = NULL;
    pkey->d = NULL;

    pkey->p    = BN_bin2bn(secureP.data(), secureP.size(), NULL);
    pkey->q    = BN_bin2bn(secureQ.data(), secureQ.size(), NULL);
    pkey->dmp1 = BN_bin2bn(secureDmp1.data(), secureDmp1.size(), NULL);
    pkey->dmq1 = BN_bin2bn(secureDmq1.data(), secureDmq1.size(), NULL);
    pkey->iqmp = BN_bin2bn(secureIqmp.data(), secureIqmp.size(), NULL);

I did my homework on Google/Stackoverflow/OpenSSL docu, but I haven't been able to find out any good way to do this, while it is obvious that openssl needs to know this by deafult for its internals.
Would you have any hint on where next with this?

Thank you,
Jan

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Chinese remainder algorithm

Thulasi Goriparthi
Hello Jan,

Decide on what your public exponent(e) should be, and either use
RSA_X931_derive_ex() if you are using an older openssl which supports
this function or follow rsa_builtin_keygen() from crypto/rsa/rsa_gen.c
on how to derive private exponent(d) and modulus(n).

By the way, technically, you do not need private exponent(d) for
signing, as you already have CRT components.

What is the function that complained about missing d?

Thanks,
Thulasi.

On 31 July 2018 at 16:19, Jan Bilek <[hidden email]> wrote:

> Hi all,
>
> I need to reconstruct public and private keys for data signing operation
> from p, q, dmp1, dmq1 and iqmp. When I fill values in as per below then
> OpenSSL complains about missing d.
>
>     RSA* pkey = RSA_new();
>     pkey->n = NULL;
>     pkey->e = NULL;
>     pkey->d = NULL;
>
>     pkey->p    = BN_bin2bn(secureP.data(), secureP.size(), NULL);
>     pkey->q    = BN_bin2bn(secureQ.data(), secureQ.size(), NULL);
>     pkey->dmp1 = BN_bin2bn(secureDmp1.data(), secureDmp1.size(), NULL);
>     pkey->dmq1 = BN_bin2bn(secureDmq1.data(), secureDmq1.size(), NULL);
>     pkey->iqmp = BN_bin2bn(secureIqmp.data(), secureIqmp.size(), NULL);
>
> I did my homework on Google/Stackoverflow/OpenSSL docu, but I haven't been
> able to find out any good way to do this, while it is obvious that openssl
> needs to know this by deafult for its internals.
> Would you have any hint on where next with this?
>
> Thank you,
> Jan
>
> --
> openssl-users mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
>
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Chinese remainder algorithm

Jan Bilek
Hi Thulasi,

Thank you for your email, it was an inspiration for our team to follow up.

Final solution then looks like this:

bool InitKey(RSA_ptr& pkey) {
  //Recalculate Modulus from provided components

  BnCtx ctx;
  {
    const BIGNUM* p;
    const BIGNUM* q;
    RSA_get0_factors(pkey.get(), &p, &q);
    auto n = BN_new();
    BN_mul(n, p, q, ctx.get());

    //Assign default exponent
    //Default Public exponent 65537
    const unsigned char defaultPublicExponent[] = {0x01, 0x00, 0x01};
    auto e = BN_bin2bn(defaultPublicExponent, sizeof(defaultPublicExponent), nullptr);
    RSA_set0_key(pkey.get(), n, e, nullptr);
  }

#ifdef DEBUG
  size_t modulusLength = RSA_size(pkey.get());
  std::cout << "modulusLength (n):      " << modulusLength << std::endl;
  std::cout << "modulusLength * 8 (n bits):      " << modulusLength * 8 << std::endl;
#endif

  //Recalculate private key
  auto r0 = BN_CTX_get(ctx.get());
  auto r1 = BN_CTX_get(ctx.get());
  auto r2 = BN_CTX_get(ctx.get());
  auto r3 = BN_CTX_get(ctx.get());

  {
    const BIGNUM* p;
    const BIGNUM* q;
    RSA_get0_factors(pkey.get(), &p, &q);

    //Calculate d
    //p-1
    if (!BN_sub(r1, p, BN_value_one()))
      return false;
    //q-1
    if (!BN_sub(r2, q, BN_value_one()))
      return false;
  }
  //(p-1)(q-1)
  if (!BN_mul(r0, r1, r2, ctx.get()))
    return false;

  if (!BN_gcd(r3, r1, r2, ctx.get()))
    return false;

  //LCM((p-1)(q-1))
  if (!BN_div(r0, nullptr, r0, r3, ctx.get()))
    return false;

  BnCtx ctx2;
  if (!ctx2.get()) {
    return false;
  }

  //d
  {
    const BIGNUM* e;
    RSA_get0_key(pkey.get(), nullptr, &e, nullptr);
    auto d = BN_mod_inverse(nullptr, e, r0, ctx2.get());
    if (!d)
      return false;
    RSA_set0_key(pkey.get(), nullptr, nullptr, d);
  }

  return true;
}

void RecalculateRsaKeyFromItsFactorsAndParams () {
  ....
  RSA_ptr pkey(RSA_new(), ::RSA_free);
  RSA_set0_key(pkey.get(), BN_new(), BN_new(), BN_new());
  RSA_set0_factors(pkey.get(),
      BN_bin2bn(secureP.data(), secureP.size(), nullptr),
      BN_bin2bn(secureQ.data(), secureQ.size(), nullptr));
  RSA_set0_crt_params(pkey.get(),
      BN_bin2bn(secureDmp1.data(), secureDmp1.size(), nullptr),
      BN_bin2bn(secureDmq1.data(), secureDmq1.size(), nullptr),
      BN_bin2bn(secureIqmp.data(), secureIqmp.size(), nullptr));

  if (!InitKey(pkey))
}

Hope this is going to help someone one day :)

Kind Regards,
Jan

On Wed, Aug 1, 2018 at 7:33 PM Thulasi Goriparthi <[hidden email]> wrote:
Hello Jan,

Decide on what your public exponent(e) should be, and either use
RSA_X931_derive_ex() if you are using an older openssl which supports
this function or follow rsa_builtin_keygen() from crypto/rsa/rsa_gen.c
on how to derive private exponent(d) and modulus(n).

By the way, technically, you do not need private exponent(d) for
signing, as you already have CRT components.

What is the function that complained about missing d?

Thanks,
Thulasi.

On 31 July 2018 at 16:19, Jan Bilek <[hidden email]> wrote:
> Hi all,
>
> I need to reconstruct public and private keys for data signing operation
> from p, q, dmp1, dmq1 and iqmp. When I fill values in as per below then
> OpenSSL complains about missing d.
>
>     RSA* pkey = RSA_new();
>     pkey->n = NULL;
>     pkey->e = NULL;
>     pkey->d = NULL;
>
>     pkey->p    = BN_bin2bn(secureP.data(), secureP.size(), NULL);
>     pkey->q    = BN_bin2bn(secureQ.data(), secureQ.size(), NULL);
>     pkey->dmp1 = BN_bin2bn(secureDmp1.data(), secureDmp1.size(), NULL);
>     pkey->dmq1 = BN_bin2bn(secureDmq1.data(), secureDmq1.size(), NULL);
>     pkey->iqmp = BN_bin2bn(secureIqmp.data(), secureIqmp.size(), NULL);
>
> I did my homework on Google/Stackoverflow/OpenSSL docu, but I haven't been
> able to find out any good way to do this, while it is obvious that openssl
> needs to know this by deafult for its internals.
> Would you have any hint on where next with this?
>
> Thank you,
> Jan
>
> --
> openssl-users mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
>
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users