简体   繁体   English

如何通过在Java中指定不同的输入来生成有效的RSA 1024位公钥和私钥?

[英]How can I generate valid RSA 1024 bits public and private keys by specifying different inputs in java?

(if you're coming new to the question, jump to the EDIT, EDIT section) (如果您是新来的问题,请跳至EDIT,EDIT部分)

I can generate random valid RSA 1024 bit public and private keys by using the following code: 我可以使用以下代码生成随机有效的RSA 1024位公用密钥和专用密钥:

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");    
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKeyGenerated = keyPair.getPublic(); //Sun RSA public key, 1024 bits
PrivateKey privateKeyGenerated = keyPair.getPrivate(); //sun.security.rsa.RSAPrivateCrtKeyImpl@fffbfe07

The comments in the above code give the details from the debugger. 上面代码中的注释提供了调试器的详细信息。

Rather than randomly generating the public and private keys I'd like to specify inputs to generate valid keys. 与其随机生成公钥和私钥,我不希望指定输入以生成有效密钥。 Something like ( link which is in the comments below): 类似于(以下评论中的链接 ):

SecureRandom secureRandom = new SecureRandom();
BigInteger p = new BigInteger("41");
BigInteger q = new BigInteger("13");
BigInteger g = new BigInteger("17");
//http://www.javadocexamples.com/java_source/sun/security/provider/DSAKeyPairGenerator.java.html
//copying the methods generateKeyPair, generateX, generateY
KeyPair keyPair = generateKeyPair(p, q, g, secureRandom);
PublicKey publicKeyGenerated = keyPair.getPublic(); //Sun DSA Public Key
PrivateKey privateKeyGenerated = keyPair.getPrivate(); //DSAPrivateKey@fffa5e6a

Using the above code I don't get valid RSA keys like in my first example. 使用上面的代码,我没有像第一个示例那样获得有效的RSA密钥。

How can I generate my own valid RSA 1024 bit public and private keys by specifying different inputs in java? 如何通过在Java中指定不同的输入来生成自己的有效RSA 1024位公用和专用密钥?

EDIT , in response to Robert: 编辑 ,以回应罗伯特:

Yes, I wish to create public and private keys using user defined values, not random. 是的,我希望使用用户定义的值(而非随机值)创建公钥和私钥。 In response to the link you provided I wrote this: 为了回应您提供的链接,我这样写:

BigInteger q = new BigInteger("114...15741");  //big prime number
BigInteger g = new BigInteger("65537"); //modulus
RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(q, g);
RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(q, g);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey = kf.generatePublic(publicSpec);
PrivateKey privateKey = kf.generatePrivate(privateSpec);

I created random keys then put the values for the exponent and modulus I got for the public key in the variables q and g above. 我创建了随机密钥,然后将上面获得的公共变量的指数和模数的值放在上面的变量qg中 I get the same public key but I don't get the same private key. 我有相同的公钥,但没有相同的私钥。 I tried adding another large prime, instead of q but I'm not really getting the answer I'd expect. 我尝试添加另一个大质数,而不是q,但是我并没有真正得到期望的答案。 The debugger shows a difference. 调试器显示出差异。 How do I create a valid public and private key? 如何创建有效的公钥和私钥?

EDIT , EDIT , after response to mnistic 编辑编辑 ,响应mnistic之后

To pull things a bit more together 让事情更加紧密

//randomly generate public and private keys
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");    
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKeyGenerated = keyPair.getPublic(); //Sun RSA public key, 1024 bits
PrivateKey privateKeyGenerated = keyPair.getPrivate(); //sun.security.rsa.RSAPrivateCrtKeyImpl@fffbfe07

//pull out the exponents and modulus
BigInteger publicExponent = ((RSAPublicKey)keyPair.getPublic()).getPublicExponent();
BigInteger privateExponent = ((RSAPrivateKey)keyPair.getPrivate()).getPrivateExponent();
BigInteger modulus = ((RSAPublicKey)keyPair.getPublic()).getModulus();

//generate public and private keys using the above details
RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(modulus, publicExponent);
RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(modulus, privateExponent);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey = kf.generatePublic(publicSpec);
PrivateKey privateKey = kf.generatePrivate(privateSpec);

//check to see that the keys are the same
System.out.println((new BigInteger(publicKeyGenerated.getEncoded())).toString());
System.out.println((new BigInteger(publicKey.getEncoded())).toString());
System.out.println((new BigInteger(privateKeyGenerated.getEncoded())).toString());
System.out.println((new BigInteger(privateKey.getEncoded())).toString());
//the private keys are different :(

The private keys are different, what's happening here? 私钥是不同的,这是怎么回事?

You are passing the public exponent to both RSAPublicKeySpec and RSAPrivateKeySpec , which is wrong. 你是路过的市民指数既RSAPublicKeySpecRSAPrivateKeySpec ,这是不对的。 RSAPrivateKeySpec expects the private exponent. RSAPrivateKeySpec需要专用指数。 If you want to regenerate the key from your first code snippet, you can obtain the modulus and the exponents with: 如果要从第一个代码段中重新生成密钥,则可以使用以下方法获取模量和指数:

BigInteger publicExponent = ((RSAPublicKey)keyPair.getPublic()).getPublicExponent();
BigInteger privateExponent = ((RSAPrivateKey)keyPair.getPrivate()).getPrivateExponent();
BigInteger modulus = ((RSAPublicKey)keyPair.getPublic()).getModulus();

And then regenerate the key with: 然后使用以下方法重新生成密钥:

RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(modulus, publicExponent);
RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(modulus, privateExponent);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey = kf.generatePublic(publicSpec);
PrivateKey privateKey = kf.generatePrivate(privateSpec);

Note: To get the private key encoding to match, you can try the following (using RSAPrivateCrtKeySpec : 注意:要获取匹配的私钥编码,可以尝试以下操作(使用RSAPrivateCrtKeySpec

BigInteger crtCoefficient = ((RSAPrivateCrtKey)keyPair.getPrivate()).getCrtCoefficient();
BigInteger primeExponentP = ((RSAPrivateCrtKey)keyPair.getPrivate()).getPrimeExponentP();
BigInteger primeExponentQ = ((RSAPrivateCrtKey)keyPair.getPrivate()).getPrimeExponentQ();
BigInteger p = ((RSAPrivateCrtKey)keyPair.getPrivate()).getPrimeP();
BigInteger q = ((RSAPrivateCrtKey)keyPair.getPrivate()).getPrimeQ();
BigInteger publicExponent = ((RSAPrivateCrtKey)keyPair.getPrivate()).getPublicExponent();
BigInteger privateExponent = ((RSAPrivateCrtKey)keyPair.getPrivate()).getPrivateExponent();
RSAPrivateCrtKeySpec crtKeySpec = new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, p, q, primeExponentP, primeExponentQ, crtCoefficient);
...
PrivateKey privateKey = kf.generatePrivate(crtKeySpec);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM