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

Generating RSA key with public exponent other than 65537 (0x10001 in hex)

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 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);

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

谢谢。


通常通过平台实现将密钥对生成限制在Java卡上的某些值上。这当然是公钥指数的情况。

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

1
2
3
4
5
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参数的。现在,如果您想要一个随机的公共指数,您可以使用一个技巧:

1
2
3
4
5
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卡代码不遵守Java卡的最佳实践,只有演示代码。