如何在 Java 中生成给定 RSA 私钥的固定长度指数?

How to generate fixed length exponent of a given RSA private key in Java?

我需要 RSA 私钥指数的十六进制始终具有固定长度,即 512 字节。为此,指数本身的长度应为 2045-2048 个字符。然后只有它的十六进制长度为512。这是代码:

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.spec.RSAPrivateKeySpec;

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp1 = kpg.genKeyPair();
PrivateKey privateKey1 = kp1.getPrivate();

KeyFactory keyFac = KeyFactory.getInstance("RSA"); 
RSAPrivateKeySpec pkSpec1 = keyFac.getKeySpec(privateKey1, RSAPrivateKeySpec.class);
BigInteger encPrivateKeyExponent = pkSpec1.getPrivateExponent();
String encPrivateKeyExponentHex = encPrivateKeyExponent.toString(16);  // hex of exponent

我面临的问题是:每次代码为运行时,encPrivateKeyExponentHex的长度不同(在509-512字节范围内)取决于关于 encPrivateKeyExponent 的长度。我每次都需要十六进制长度正好是 512 字节。有没有办法确保这一点?

没有直接生成 fixed-length 基数表示的 BigInteger 例程。最简单的方法是像您一样使用 .toString(16),然后根据需要填充前导 0 字符。或者您可以编写一个 fixed-length 输出例程,例如:

char[] out = new char[512]; // probably best to make 512 a named constant
for( int i = 512; --i >= 0; ){
    out[i] = Character.forDigit (privexpt.intValue()&0xF, 16);
    privexpt = privexpt.shiftRight(4);
}
String result = new String (out);

但是,需要注意两点:

  • 您不需要 KeyFactory 和 Spec-class 来获取私有指数; RSA KeyPair 的私有部分实现了 java.security.interfaces.RSAPrivateKey.getPrivateExponent

  • 如果您打算在将来的某个时间或其他地方对此密钥对进行 private-key 操作,仅保存或传输私有指数不是一个好方法。基本上,大约 30 年来的所有 RSA 实现都不会像维基百科的前几段或从几十年前的简短新闻剪报或摘录中复制的数十亿博客那样简单地执行 'c up d mod n',而是使用更复杂的 private-key 支持更高效的 'Chinese Remainder Theorem' 计算,如您阅读所有 the wikipedia article, or look at a text by an author who actually knows about modern cryptography. Java crypto does support RSA-CRT private-keys, like all private-keys, in a industry standard encoding (PKCS8) that is fairly widely (though not universally) supported; this is noted, though not really explained, in javadoc for the top-level interface java.security.Key

  • 所述