Java(111):非对称加密RSA的使用(openssl生成RSA公私钥对)
1、openssl生成RSA公私钥对
[root@loaclhost ~]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
#生成RSA私钥:
[root@loaclhost ~]# openssl
OpenSSL> genrsa -out rsa_private_key.pem 1024
Generating RSA private key, 1024 bit long modulus
...........................................................++++++
.......++++++
e is 65537 (0x10001)
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform pem -nocrypt -out rsa_private_key_8.pem
#生成RSA公钥
OpenSSL> rsa -in rsa_private_key_8.pem -pubout -out rsa_public_key.pem
公钥:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeOvgowlgzAiPdIdBsFK5Yk9dH
B3BXQa1IieIkRbxC7ZGYiXJELbzHi5vcmmFuadKQBA1BltR3yNdIptRM9/NRQtVo
e+kuFIU1X/MgFhIGlP4O56LL5L8RqOg8yj/EOJzYBU7ioMZX6f2uDjCJ0s7Nx45y
/cr9RQJZbv5WAx4YyQIDAQAB
-----END PUBLIC KEY-----
私钥:
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAN46+CjCWDMCI90h
0GwUrliT10cHcFdBrUiJ4iRFvELtkZiJckQtvMeLm9yaYW5p0pAEDUGW1HfI10im
1Ez381FC1Wh76S4UhTVf8yAWEgaU/g7nosvkvxGo6DzKP8Q4nNgFTuKgxlfp/a4O
MInSzs3HjnL9yv1FAllu/lYDHhjJAgMBAAECgYAZqZWen1KwET8y+gSndnvrnqbt
fN5sNRldlw6WQbdLw0Nc6gJX/TAfmu+Uuf8mUPIPz2f4ewJuErNJoHpDqR5fvLeP
YQNdJNKFK3wSqc58pMBkABMJEod94RbTEgDtC8FRZUbz98IUVMTwByLrRqgoZqAW
3XYU9zaYdj5QzNvvQQJBAP14trvc3DwkNq3YwJ+iJfsYbTJ21nNyYaJkUx2sb43p
KPOdpx+dmmlkk+uRYdJK9eLp+0m4LsARYfGR1Vrm2UcCQQDgcnm2wSbPuwqrkPbO
njRhtbUtFgAUMIevOAAbZEa1CmBeQ5eOfDirlSa3W/ZtL3GkfZWNv+rBKuOSTWoW
vIVvAkEAyz4uGDkihz7qcT+qRNY56jtN4/cSQgPncdVMKDEKSho5cg5p4Zn4JKY3
Td6HN55Px6GikxwSsIO/q3oqP/d3JQJAP+mZKydZS/HxGeXPwgpe1CwQCWSoZRdk
q8qAjUxCri7kPjN1JsfMw19XhQMU6waFj9eLDLBHwvXZk8GjohHQ1QJAKNzrOU8u
KuiV5qpnU+TXofdnngX+ovveaCUJDh3Mg1tFeBJ7R+rB1nub8sGUgdnPmDaE3tpp
N3vUqLzUXzbo1Q==
-----END PRIVATE KEY----
openssl生成的公钥和私钥是Base64的,用时需要用base64解码
2、RSA加密和解密方法
/**
* 公钥加密
* @param publicKey 公钥
* @param obj 明文
* @return byte[] 密文
*/
public static byte[] encrypt(RSAPublicKey publicKey, byte[] obj) throws Exception {
Cipher cipher =Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
//返回加密后的内容
return cipher.doFinal(obj);
}
/**
* 私钥解密
* @param privateKey 公钥
* @param obj 密文
* @return byte[] 密文
*/
public static byte[] decrypt(RSAPrivateKey privateKey, byte[] obj)throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//返回解密后的数组
return cipher.doFinal(obj);
}
3、Base64编码和解码
maven
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.11</version> </dependency>
代码:
/**
* 编码
* @param txt byte字节数组
* @return encode Base64编码
*/
public static byte[] encode(byte[] txt) {
return org.apache.commons.codec.binary.Base64.encodeBase64(txt);
}
/**
* 解码
* @param txt 编码后的byte
* @return decode Base64解码
*/
public static byte[] decode(String txt){
return org.apache.commons.codec.binary.Base64.decodeBase64(txt);
}
4、调用加解密
操作步骤
备注: openssl生成的公钥和私钥是Base64的,用时需要进行解码
1、先对公钥进行进行Base64解码。
2、再用解码后的公钥进行RSA加密(对密文进行Base64编码)
3、然后对私钥Base64解码
4、最后用解码的私钥进行RSA解密(输入:密文解码后入参,输出:转成字符串输出)。
final static String PUBKEY="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeOvgowlgzAiPdIdBsFK5Yk9dH\n" +
"B3BXQa1IieIkRbxC7ZGYiXJELbzHi5vcmmFuadKQBA1BltR3yNdIptRM9/NRQtVo\n" +
"e+kuFIU1X/MgFhIGlP4O56LL5L8RqOg8yj/EOJzYBU7ioMZX6f2uDjCJ0s7Nx45y\n" +
"/cr9RQJZbv5WAx4YyQIDAQAB";
final static String PRIKEY="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAN46+CjCWDMCI90h\n" +
"0GwUrliT10cHcFdBrUiJ4iRFvELtkZiJckQtvMeLm9yaYW5p0pAEDUGW1HfI10im\n" +
"1Ez381FC1Wh76S4UhTVf8yAWEgaU/g7nosvkvxGo6DzKP8Q4nNgFTuKgxlfp/a4O\n" +
"MInSzs3HjnL9yv1FAllu/lYDHhjJAgMBAAECgYAZqZWen1KwET8y+gSndnvrnqbt\n" +
"fN5sNRldlw6WQbdLw0Nc6gJX/TAfmu+Uuf8mUPIPz2f4ewJuErNJoHpDqR5fvLeP\n" +
"YQNdJNKFK3wSqc58pMBkABMJEod94RbTEgDtC8FRZUbz98IUVMTwByLrRqgoZqAW\n" +
"3XYU9zaYdj5QzNvvQQJBAP14trvc3DwkNq3YwJ+iJfsYbTJ21nNyYaJkUx2sb43p\n" +
"KPOdpx+dmmlkk+uRYdJK9eLp+0m4LsARYfGR1Vrm2UcCQQDgcnm2wSbPuwqrkPbO\n" +
"njRhtbUtFgAUMIevOAAbZEa1CmBeQ5eOfDirlSa3W/ZtL3GkfZWNv+rBKuOSTWoW\n" +
"vIVvAkEAyz4uGDkihz7qcT+qRNY56jtN4/cSQgPncdVMKDEKSho5cg5p4Zn4JKY3\n" +
"Td6HN55Px6GikxwSsIO/q3oqP/d3JQJAP+mZKydZS/HxGeXPwgpe1CwQCWSoZRdk\n" +
"q8qAjUxCri7kPjN1JsfMw19XhQMU6waFj9eLDLBHwvXZk8GjohHQ1QJAKNzrOU8u\n" +
"KuiV5qpnU+TXofdnngX+ovveaCUJDh3Mg1tFeBJ7R+rB1nub8sGUgdnPmDaE3tpp\n" +
"N3vUqLzUXzbo1Q==";
public static void main(String[] args)throws Exception {
byte[] decode = decode(PUBKEY);
RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(decode));
//执行加密和解密过程
String InData="Hello World!";
//得到要加密内容的数组
byte[] byteInData =InData.getBytes("UTF-8");
//用公钥加密
byte[] cipherByte= encrypt(publicKey,byteInData);
String cipher=new String(encode(cipherByte));
System.out.println("RSA加密,密文:"+cipher);
//用私钥解密
byte[] decode_pri = decode(PRIKEY);
RSAPrivateCrtKey priKey = (RSAPrivateCrtKey)KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decode_pri));
byte[] plainByte =decrypt(priKey,decode(cipher));
System.out.println("RSA私钥解密,明文:"+new String(plainByte));
}
5、代码示例
package jmj;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* Description :
*
* @author : HMF
* Date : Created in 22:04 2023/3/13
* @version :
*/
public class RSAUtil {
final static String PUBKEY="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeOvgowlgzAiPdIdBsFK5Yk9dH\n" +
"B3BXQa1IieIkRbxC7ZGYiXJELbzHi5vcmmFuadKQBA1BltR3yNdIptRM9/NRQtVo\n" +
"e+kuFIU1X/MgFhIGlP4O56LL5L8RqOg8yj/EOJzYBU7ioMZX6f2uDjCJ0s7Nx45y\n" +
"/cr9RQJZbv5WAx4YyQIDAQAB";
final static String PRIKEY="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAN46+CjCWDMCI90h\n" +
"0GwUrliT10cHcFdBrUiJ4iRFvELtkZiJckQtvMeLm9yaYW5p0pAEDUGW1HfI10im\n" +
"1Ez381FC1Wh76S4UhTVf8yAWEgaU/g7nosvkvxGo6DzKP8Q4nNgFTuKgxlfp/a4O\n" +
"MInSzs3HjnL9yv1FAllu/lYDHhjJAgMBAAECgYAZqZWen1KwET8y+gSndnvrnqbt\n" +
"fN5sNRldlw6WQbdLw0Nc6gJX/TAfmu+Uuf8mUPIPz2f4ewJuErNJoHpDqR5fvLeP\n" +
"YQNdJNKFK3wSqc58pMBkABMJEod94RbTEgDtC8FRZUbz98IUVMTwByLrRqgoZqAW\n" +
"3XYU9zaYdj5QzNvvQQJBAP14trvc3DwkNq3YwJ+iJfsYbTJ21nNyYaJkUx2sb43p\n" +
"KPOdpx+dmmlkk+uRYdJK9eLp+0m4LsARYfGR1Vrm2UcCQQDgcnm2wSbPuwqrkPbO\n" +
"njRhtbUtFgAUMIevOAAbZEa1CmBeQ5eOfDirlSa3W/ZtL3GkfZWNv+rBKuOSTWoW\n" +
"vIVvAkEAyz4uGDkihz7qcT+qRNY56jtN4/cSQgPncdVMKDEKSho5cg5p4Zn4JKY3\n" +
"Td6HN55Px6GikxwSsIO/q3oqP/d3JQJAP+mZKydZS/HxGeXPwgpe1CwQCWSoZRdk\n" +
"q8qAjUxCri7kPjN1JsfMw19XhQMU6waFj9eLDLBHwvXZk8GjohHQ1QJAKNzrOU8u\n" +
"KuiV5qpnU+TXofdnngX+ovveaCUJDh3Mg1tFeBJ7R+rB1nub8sGUgdnPmDaE3tpp\n" +
"N3vUqLzUXzbo1Q==";
public static void main(String[] args)throws Exception {
byte[] decode = decode(PUBKEY);
RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(decode));
//执行加密和解密过程
String InData="Hello World!";
//得到要加密内容的数组
byte[] byteInData =InData.getBytes("UTF-8");
//用公钥加密
byte[] cipherByte= encrypt(publicKey,byteInData);
String cipher=new String(encode(cipherByte));
System.out.println("RSA加密,密文:"+cipher);
//用私钥解密
byte[] decode_pri = decode(PRIKEY);
RSAPrivateCrtKey priKey = (RSAPrivateCrtKey)KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decode_pri));
byte[] plainByte =decrypt(priKey,decode(cipher));
System.out.println("RSA私钥解密,明文:"+new String(plainByte));
}
/**
* 编码
* @param txt byte字节数组
* @return encode Base64编码
*/
public static byte[] encode(byte[] txt) {
return org.apache.commons.codec.binary.Base64.encodeBase64(txt);
}
/**
* 解码
* @param txt 编码后的byte
* @return decode Base64解码
*/
public static byte[] decode(String txt){
return org.apache.commons.codec.binary.Base64.decodeBase64(txt);
}
/**
* 公钥加密
* @param publicKey 公钥
* @param obj 明文
* @return byte[] 密文
*/
public static byte[] encrypt(RSAPublicKey publicKey, byte[] obj) throws Exception {
Cipher cipher =Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
//返回加密后的内容
return cipher.doFinal(obj);
}
/**
* 私钥解密
* @param privateKey 公钥
* @param obj 密文
* @return byte[] 密文
*/
public static byte[] decrypt(RSAPrivateKey privateKey, byte[] obj)throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//返回解密后的数组
return cipher.doFinal(obj);
}
}
执行结果:
参考: