Java RSA密钥转换,从RSAPrivateKey得到RSAPublicKey

概述:

在Java编程中,我们经常用到如下一段代码来生成RSA公私钥,分别拿到公私钥然后加解密计算:

KeyPairGenerator keyPairGen;
keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048, new SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

本文讲述仅有RSAPrivateKey privateKey,没有KeyPair keyPair,如何通过RSAPrivateKey privateKey得到RSAPublicKey publicKey

分析RSAPrivateKey:

RSAPrivateKey privateKey,通过函数privateKey.getAlgorithm()查看,或者通过privateKey.getEncoded()数据分析,可以得到默认是PKCS#8格式,
privateKey.getEncoded()的数据例子:

Java RSA密钥转换,从RSAPrivateKey得到RSAPublicKey_第1张图片
通过TLV分析工具查看:
Java RSA密钥转换,从RSAPrivateKey得到RSAPublicKey_第2张图片
Java RSA密钥转换,从RSAPrivateKey得到RSAPublicKey_第3张图片
可以看到,RSAPrivateKey privateKey里面,RSA密钥的参数N、E、D、P、Q等都包含在内的。
其中N、E是私钥对应的公钥RSAPublicKey publicKey,所需的全部参数。
因此,是可以从RSAPrivateKey privateKey拿到对应的RSAPublicKey publicKey

开发环境:

`IDE:eclipse版本4.20.0
编译器:JDK1.8
导入的包:bouncycastle,jar文件名bcprov-jdk18on-171.jar

转换函数:

public static byte[] p8PrvKey2P1PrvKeyBytes(PrivateKey privateKey) throws Exception {
      PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance(privateKey.getEncoded());
       ASN1Encodable privateKeyPKCS1ASN1Encodable = privateKeyInfo.parsePrivateKey();
       ASN1Primitive asn1Primitive = privateKeyPKCS1ASN1Encodable.toASN1Primitive();        
       return asn1Primitive.getEncoded();
   } 
   	
public static RSAPublicKey rsaGetPubKeyFromPriKey(RSAPrivateKey privateKey) {
	RSAPublicKeySpec rsaPubKeySpec = null;
	KeyFactory keyFactory = null;
	org.bouncycastle.asn1.pkcs.RSAPrivateKey rP = null;

	try {
		keyFactory = KeyFactory.getInstance("RSA");
		rP = org.bouncycastle.asn1.pkcs.RSAPrivateKey.getInstance(p8PrvKey2P1PrvKeyBytes(privateKey));
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	try {
		keyFactory = KeyFactory.getInstance("RSA");
		rsaPubKeySpec = new RSAPublicKeySpec(rP.getModulus(), rP.getPublicExponent());
		return (RSAPublicKey) keyFactory.generatePublic(rsaPubKeySpec);
	} catch (InvalidKeySpecException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		return null;
	} catch (NoSuchAlgorithmException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		return null;
	}
}

注意导入bcprov-jdk18on-171.jar中类

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;

还要注意,bouncycastle里面有RSAPrivateKey
jdk自带公共:java.security.interfaces.RSAPrivateKey;

bouncycastle包里面的:org.bouncycastle.asn1.pkcs.RSAPrivateKey

测试代码:

public static void main(String[] args) {		
	testRsa();
}

public static void testRsa() {
	KeyPairGenerator keyPairGen;
	try {
		keyPairGen = KeyPairGenerator.getInstance("RSA");
		
		keyPairGen.initialize(2048, new SecureRandom());
   
		KeyPair keyPair = keyPairGen.generateKeyPair();

		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
		
		//System.out.println("privateKey:" + hexToString(privateKey.getEncoded(), 0, privateKey.getEncoded().length));
		//RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		RSAPublicKey publicKey = rsaGetPubKeyFromPriKey(privateKey);
		
		String out1 = encrypt("1234567890", publicKey);
		System.out.println("encrypt:" + out1);
		String out2 = decrypt(out1, privateKey);
		System.out.println("decrypt:" + out2);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}        
}


public static String encrypt(String str, RSAPublicKey publicKey) throws Exception {
	//base64编码的公钥
	//byte[] decoded = Base64.getDecoder().decode(publicKey);
	//RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
	//RSA加密
	Cipher cipher = Cipher.getInstance("RSA");
	cipher.init(Cipher.ENCRYPT_MODE, publicKey);
	String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8")));
	return outStr;
}
public static String decrypt(String str, RSAPrivateKey privateKey) throws Exception {
	//64位解码加密后的字符串
	byte[] inputByte = Base64.getDecoder().decode(str);
	//base64编码的私钥
	//byte[] decoded = Base64.getDecoder().decode(privateKey);
	//RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
	//RSA解密
	Cipher cipher = Cipher.getInstance("RSA");
	cipher.init(Cipher.DECRYPT_MODE, privateKey);
	String outStr = new String(cipher.doFinal(inputByte));
	return outStr;
}

测试结果:

在这里插入图片描述

你可能感兴趣的:(java,开发语言)