2017-02-04 61 views
0

我需要RSA私钥指数的十六进制为固定长度,即512字节。为此,指数本身应该是2045-2048个字符长。那么只有其十六进制将是长度512这里是代码:如何在Java中生成给定RSA私钥的固定长度指数?

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个字节。有没有办法确保这一点?

回答

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和规格一流,以获得私人指数; RSA KeyPair的私有部分实现java.security.interfaces.RSAPrivateKey.getPrivateExponent

  • ,如果你打算在未来某个时间或其他地方,这个密钥对做私钥操作(S),保存或仅发送私人指数是不是一个好办法。基本上,大约30年来所有的RSA实现都不是简单地按照几十年前的简短新闻剪报或exceprts复制的维基百科前几段或数十亿博客所示的那样进行,而是使用更复杂的私有如果您阅读全部the wikipedia article,或者查看实际上了解现代密码学的作者的文本,则支持更高效的“中国剩余定理”计算。 Java加密确实支持RSA-CRT私钥,就像所有私钥一样,采用工业标准编码(PKCS8),这种编码相当广泛(尽管不是普遍的)支持;这是注意到,虽然没有真正解释,在javadoc为顶级接口java.security.Key

+0

感谢您的方法和建议!请记住。 – Pratap