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

时间:2017-02-04 03:22:58

标签: java cryptography rsa private-key java-security

我需要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的长度< / strong>即可。我需要每次都将十六进制长度精确地设置为512字节。有没有办法确保这个?

1 个答案:

答案 0 :(得分:2)

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

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

  • 如果您打算在将来某个时间或其他地方为此密钥对执行私钥操作,则仅保存或传输私有指数不是一个好方法。基本上所有RSA实施大约30年不是简单地做'维护d mod n',如维基百科的前几段或数十亿博客从几十年前的简短新闻剪报或异常复制中复制,而是使用更复杂的私人-key支持更有效的“中国剩余定理”计算,如果您阅读了所有the wikipedia article,或者查看实际了解现代密码学的作者的文本。 Java加密支持RSA-CRT私钥,就像所有私钥一样,采用行业标准编码(PKCS8),支持相当广泛(尽管不是普遍);在javadoc中为顶级界面java.security.Key

  • 注意到了这一点,尽管没有真正解释过