为什么 gcrypt 在从 SSL 格式转换为 gcrypt 时说要重新计算 RSA 密钥的系数?
Why does gcrypt say to recalculate the coefficient of an RSA key when converting from SSL format to gcrypt?
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.
答案是重新计算"u"是无关紧要的。只需交换 "p" 和 "q" 的用法即可。
作为对 gcrypt 的一般评论,非对称加密 API 很糟糕。真惨。
不支持从任何格式的文件加载密钥。
不支持简单地 encrypt/decrypt 缓冲区。相反,您需要先将缓冲区转换为 MPI,然后才能将其转换为 S 表达式。加密后,您需要展开生成的 S 表达式以获得正确的部分,然后调用另一个函数来获取数据本身。解密在创建 S 表达式以从缓冲区解密时需要稍微复杂一些,但检索数据只是一个函数调用。
私钥 S 表达式的参数与标准 PKCS#1 格式的值不匹配(尽管如本问答所述,转换相当容易)。为什么不呢?
在调查过程中,我发现还有另一个 GNU 加密库。为什么他们保持两个我不知道。另一个叫做 "nettle" 并且更好:
*) 它使用 GMP 库来处理多精度整数,而不是像 gcrypt 那样拥有自己的类型 (mpi_t)。
*)它支持从各种格式的文件中加载密钥(我用它作为我自己的代码加载密钥以与gcrypt一起使用的基础)。
*) 支持各种格式的转换(PEM->DER, DER->Sexp)。
*)支持多种对称加密算法和模式
*) 支持非对称 encryption/decryption/signing/verification.
我并没有实际使用它,所以我无法对 API 的可用性发表评论,但据我所知,它通常要好得多。
我真的不知道 nettle 的背景,但我想知道它是否只是因为 gcrypt 的 API 太糟糕而创建它,他们宁愿重新开始也不愿增强 gcrypt。
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.
答案是重新计算"u"是无关紧要的。只需交换 "p" 和 "q" 的用法即可。
作为对 gcrypt 的一般评论,非对称加密 API 很糟糕。真惨。
不支持从任何格式的文件加载密钥。
不支持简单地 encrypt/decrypt 缓冲区。相反,您需要先将缓冲区转换为 MPI,然后才能将其转换为 S 表达式。加密后,您需要展开生成的 S 表达式以获得正确的部分,然后调用另一个函数来获取数据本身。解密在创建 S 表达式以从缓冲区解密时需要稍微复杂一些,但检索数据只是一个函数调用。
私钥 S 表达式的参数与标准 PKCS#1 格式的值不匹配(尽管如本问答所述,转换相当容易)。为什么不呢?
在调查过程中,我发现还有另一个 GNU 加密库。为什么他们保持两个我不知道。另一个叫做 "nettle" 并且更好:
*) 它使用 GMP 库来处理多精度整数,而不是像 gcrypt 那样拥有自己的类型 (mpi_t)。
*)它支持从各种格式的文件中加载密钥(我用它作为我自己的代码加载密钥以与gcrypt一起使用的基础)。
*) 支持各种格式的转换(PEM->DER, DER->Sexp)。
*)支持多种对称加密算法和模式
*) 支持非对称 encryption/decryption/signing/verification.
我并没有实际使用它,所以我无法对 API 的可用性发表评论,但据我所知,它通常要好得多。
我真的不知道 nettle 的背景,但我想知道它是否只是因为 gcrypt 的 API 太糟糕而创建它,他们宁愿重新开始也不愿增强 gcrypt。