使用 65537 以外的公共指数生成 RSA 密钥(十六进制中的 0x10001)

Posted

技术标签:

【中文标题】使用 65537 以外的公共指数生成 RSA 密钥(十六进制中的 0x10001)【英文标题】:Generating RSA key with public exponent other than 65537 (0x10001 in hex) 【发布时间】:2014-08-09 08:34:21 【问题描述】:

我正在为 2048 位 RSA 实现一个 java 卡小程序。我想知道如何使用 65537 以外的公共指数 (e) 创建 RSA 密钥对。

卡生成 RSA 密钥对,并返回其公共指数 (e) 和模数 (n)。但是公共指数每次都是 65537(十六进制的 0x10001)。我的代码如下

// Initialize objects for RSA Keys and Pair
objRSAPriKey = (RSAPrivateCrtKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_CRT_PRIVATE, KeyBuilder.LENGTH_RSA_2048, false);
objRSAPubKey = (RSAPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC,  KeyBuilder.LENGTH_RSA_2048, false);
objRSAKeyPair= new KeyPair(KeyPair.ALG_RSA_CRT, KeyBuilder.LENGTH_RSA_2048);

    ...

// Generate Key Pairs    
objRSAKeyPair.genKeyPair();

objRSAPriKey = (RSAPrivateCrtKey)objRSAKeyPair.getPrivate();
objRSAPubKey = (RSAPublicKey)objRSAKeyPair.getPublic();

GetResLen = objRSAPubKey.getModulus(Rb_GetRes, BAS);
GetResLen += objRSAPubKey.getExponent(Rb_GetRes, GetResLen);

当然我知道这些key是不一样的,因为每次小程序生成key时key(n,d,p,q)的其他值都不一样。但我想知道如何生成具有 2048 位大小的公共指数的 RSA 密钥对

谢谢。

【问题讨论】:

【参考方案1】:

通常,平台实现将密钥对生成限制为 Java Card 上的某些值。公钥指数当然就是这种情况。

目前您正在构建一个公钥和私钥对,只是为了用genKeyPair 生成的引用覆盖对它们的引用。相反,您可以像这样构建密钥对:

objRSAPriKey = (RSAPrivateCrtKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_CRT_PRIVATE, KeyBuilder.LENGTH_RSA_2048, false);
objRSAPubKey = (RSAPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC,  KeyBuilder.LENGTH_RSA_2048, false);
objRSAPubKey.setExponent(myLargeExponent, 0, (short) myLargeExponent.length);
objRSAKeyPair= new KeyPair(objRSAPubKey, objRSAPriKey);
objRSAKeyPair.genKeyPair();

这将生成一个具有任何值的静态指数的公钥如果平台支持。如果不支持,请尝试使用 RSAPrivateKey 而不是也使用 CRT 参数的。现在如果你想要一个随机的公共指数,你可以使用一个技巧:

randomExponentRSAKeyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);
randomExponentRSAKeyPair.genKeyPair();
byte[] myLargeExponent = new byte[KeyBuilder.LENGTH_RSA_2048 / 8];
RSAPrivateKey tmpKey = (RSAPrivateKey)randomRSAKeyPair.getPrivate();
key.getExponent(myLargeExponent, (short) 0);

如果运行此代码,您已经创建了一个非常慢的公钥,它与另一个公钥相比没有优势,并且不应该用于代替私钥

注意:上面的 Java Card 代码不遵循 Java Card 最佳实践,仅演示代码

【讨论】:

非常感谢。实际上,我正在寻找如何使用静态指数生成公钥,您的第一个代码非常有帮助。但我不完全理解你的第二个代码。据我了解您的 cmets,我在下面修改并发布了我的代码,但它不起作用。

以上是关于使用 65537 以外的公共指数生成 RSA 密钥(十六进制中的 0x10001)的主要内容,如果未能解决你的问题,请参考以下文章

为公共指数 e 设置默认值,并将 n 作为密钥对的模数

使用模数和公共指数的 C# RSA 加密

RSA原理说明

.NET 中的 RSA 密钥指数有限制吗?

密码疑云 ——详解RSA的加密与解密

如何将公共RSA密钥上传到HSM(使用PKCS#11库)?