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

标签 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的长度都会根据encPrivateKeyExponent<的长度而变化(在509-512字节的范围内)/强>。我每次都需要十六进制长度恰好为 512 字节。有没有办法保证这一点?

最佳答案

没有直接生成固定长度基数表示的 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来获取私有(private)指数; RSA KeyPair 的私有(private)部分实现 java.security.interfaces.RSAPrivateKey.getPrivateExponent

  • 如果您打算在将来的某个时间或其他地方对此 key 对进行私钥操作,则仅保存或传输私有(private)指数并不是一个好方法。本质上,大约 30 年的所有 RSA 实现并不简单地执行“c up d mod n”,如维基百科的前几段或从几十年前的简短新闻剪报或摘录中复制的数十亿博客中所示,而是使用更复杂的私有(private)-支持更高效的“中国余数定理”计算的 key ,如您阅读 the wikipedia article 的全部内容所解释的那样,或者看看真正了解现代密码学的作者写的文本。 Java 加密确实支持 RSA-CRT 私钥,就像所有私钥一样,采用行业标准编码 (PKCS8),该编码得到相当广泛(尽管不是普遍)支持;尽管没有真正解释,但在顶级接口(interface) java.security.Key 的 javadoc 中注意到了这一点。

关于java - 如何在Java中生成给定RSA私钥的固定长度指数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42036121/

相关文章:

java - PostgreSQL 序列的 increment_by 如何与 Hibernate 的 allocationSize 一起工作?

java - Android:回调 java.lang.NullPointerException 中的 sendBroadcast 未处理的异常

c# - RSA key 对导入私钥异常

github - 在 github 操作中使用 openssl

java - 在 Stream.map() 中将 Consumer 转换为 Runnable

java - 使用 MySQL 查询的结果更新 TableView 行颜色

java - 如何在java中生成离散对数

python - 谐音替换密码 Python

security - PKCS11 中的 "mechanism"是什么?

java - 如何用Java实现RSA加解密