为什么gcrypt说在从SSL格式转换为gcrypt时重新计算RSA密钥的系数?

时间:2017-10-17 12:05:14

标签: rsa libgcrypt

libgcrypt的文档说:

An RSA private key is described by this S-expression:

(private-key
  (rsa
    (n n-mpi)
    (e e-mpi)
    (d d-mpi)
    (p p-mpi)
    (q q-mpi)
    (u u-mpi)))

...和...

p-mpi
    RSA secret prime p. 
q-mpi
    RSA secret prime q with p < q. 
u-mpi
    Multiplicative inverse u = p^{-1} mod q. 

...和...

Note that OpenSSL uses slighly different parameters: q < p and u = q^{-1} mod p.
To use these parameters you will need to swap the values and recompute u.
Here is example code to do this:

  if (gcry_mpi_cmp (p, q) > 0)
  {
      gcry_mpi_swap (p, q);
      gcry_mpi_invm (u, p, q);
  }

如果在一个p中是较小的素数而在另一个中q是较小的素数,并且鉴于交换p和q两个方程是相同的,是否真的有必要重新计算u?只交换p和q是不够的?

作为一个附带问题,我很好奇为什么gcrypt不使用与PKCS#1编码相同的值:

     RSAPrivateKey ::= SEQUENCE {
         version           Version,
         modulus           INTEGER,  -- n
         publicExponent    INTEGER,  -- e
         privateExponent   INTEGER,  -- d
         prime1            INTEGER,  -- p
         prime2            INTEGER,  -- q
         exponent1         INTEGER,  -- d mod (p-1)
         exponent2         INTEGER,  -- d mod (q-1)
         coefficient       INTEGER,  -- (inverse of q) mod p
         otherPrimeInfos   OtherPrimeInfos OPTIONAL
     }

o  modulus is the RSA modulus n.
o  publicExponent is the RSA public exponent e.
o  privateExponent is the RSA private exponent d.
o  prime1 is the prime factor p of n.
o  prime2 is the prime factor q of n.
o  exponent1 is d mod (p - 1).
o  exponent2 is d mod (q - 1).
o  coefficient is the CRT coefficient q^(-1) mod p.

1 个答案:

答案 0 :(得分:0)

答案是重新计算“你”是无关紧要的。只需交换“p”和“q”的用法,一切正常。

作为对gcrypt的一般性评论,非对称加密API非常糟糕。真的很糟糕。

  • 不支持以任何格式从文件加载密钥。

  • 不支持简单地加密/解密缓冲区。相反,您需要先将缓冲区转换为MPI,然后再将其转换为S表达式。加密后,您需要展开生成的S表达式以获得正确的部分,然后再调用另一个函数来获取数据本身。在创建S-expression以从缓冲区解密时,解密需要稍微复杂一些,但检索数据只是一个函数调用。

  • 私钥的S表达式的参数与标准PKCS#1格式的值不匹配(尽管这个问题和答案涵盖了转换,但转换相当容易)。为什么不呢?

在调查过程中,我发现还有另一个GNU加密库。为什么他们保持两个我不知道。另一个被称为“荨麻”并且好得多:

*)它将GMP库用于多精度整数,而不是像gcrypt那样拥有自己的类型(mpi_t)。

*)它支持以各种格式从文件加载密钥(我将其用作我自己的代码的基础,以加载与gcrypt一起使用的密钥)。

*)它支持各种格式的转换(PEM-&gt; DER,DER-&gt; Sexp)。

*)它支持各种对称加密算法和模式。

*)它支持非对称加密/解密/签名/验证。

我实际上并没有使用它,所以我无法评论API的可用性,但从我看到它通常要好得多。

我真的不知道nettle的背景,但我确实想知道它是否只是因为gcrypt的API非常糟糕而且他们宁愿重新开始而不是增强gcrypt。