1、公私钥生成
命令:
localhost:~ username$ openssl #打开OpenSSL程序
OpenSSL> genrsa -out rsa_private_key.pem 1024 #生成私钥,1024为密钥长度
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_pkcs8.pem #Java开发者需要将私钥转换成PKCS8格式
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem #生成公钥
OpenSSL> exit #退出OpenSSL程序
实操:
localhost:~ username$ 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_pkcs8.pem
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
writing RSA key
标准的私钥文件示例(PHP、.NET使用):
-----BEGIN RSA PRIVATE KEY-----
MIICXwIBAAKBgQDOPxXhTG5AvlVgOTZo2LfAbcuuInguZunuq+n7ErdrFZ6L7R8b
QRDwQwL4gx84HzcV/6G5XdpxQ+hkoDD3mXBHIGIN529GZ8NogzyuY7sIUvDdNPwr
LbZ1qXqn18AjO8J6rWQmYOtzbH5UwvuYu2cNh0ENWrPcK3z5XTmJRKoxiwIDAQAB
AoGBAIqGkLmcTkkqDcntY4AUX4bdt/ojqLjx4pmt2iAKuCsygCTXhRcXIrtdJven
iiZ1wNgDtKn+QaPlyocbmQgUhPXsNjy5jZ8fTNHkzLDMLY5Ur5WB7fCoPyDQHpen
RmRYw7k7uPT1lJf1vST0WL0z/HuSxGu2sG4pDxAdPMG+Xn2xAkEA6MQYymwozx+x
IvhlvXDKn87skc2hsk3qDRKZUO+Q4akGBFfDGDs2Vt9afmCLP74wArw+jF7a8lwR
Bd/9zoiWtQJBAOLVVIFeHgtls4c3s2NEQmi8wWp7HbnNMviLO2bxoYNJWst9DC7w
S+mumEZROr/AvGUr8If7tzPdK4AXGW4mjz8CQQDXlUAMw25sn8K1S/EXK09QAhvT
0uuPNGCxaOd9MdUzXBQJk6tLVxQ2E7pB0HNIP4NCFU2tPvF0hVby5Qmy74j9AkEA
m+E4YnK4OOLZ/clEaKom7O0SCcezhNTD+1NLLhJNCPinAYHcloEh2ePW1zPJKK8d
iHUqpXhQzL5nv22gVzb+ZwJBANt/Gj5GUCdrzQ02s6x+GHIWtG6Apww4hbz+d7a1
1D+dx0aMwNhAvqReaF0QDcw6I7Er8p4EU+mNnRVf6ldMjqw=
-----END RSA PRIVATE KEY-----
PKCS8处理后的私钥文件示例(Java使用)
-----BEGIN PRIVATE KEY-----
MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAM4/FeFMbkC+VWA5
NmjYt8Bty64ieC5m6e6r6fsSt2sVnovtHxtBEPBDAviDHzgfNxX/obld2nFD6GSg
MPeZcEcgYg3nb0Znw2iDPK5juwhS8N00/CsttnWpeqfXwCM7wnqtZCZg63NsflTC
+5i7Zw2HQQ1as9wrfPldOYlEqjGLAgMBAAECgYEAioaQuZxOSSoNye1jgBRfht23
+iOouPHima3aIAq4KzKAJNeFFxciu10m96eKJnXA2AO0qf5Bo+XKhxuZCBSE9ew2
PLmNnx9M0eTMsMwtjlSvlYHt8Kg/INAel6dGZFjDuTu49PWUl/W9JPRYvTP8e5LE
a7awbikPEB08wb5efbECQQDoxBjKbCjPH7Ei+GW9cMqfzuyRzaGyTeoNEplQ75Dh
qQYEV8MYOzZW31p+YIs/vjACvD6MXtryXBEF3/3OiJa1AkEA4tVUgV4eC2Wzhzez
Y0RCaLzBansduc0y+Is7ZvGhg0lay30MLvBL6a6YRlE6v8C8ZSvwh/u3M90rgBcZ
biaPPwJBANeVQAzDbmyfwrVL8RcrT1ACG9PS6480YLFo530x1TNcFAmTq0tXFDYT
ukHQc0g/g0IVTa0+8XSFVvLlCbLviP0CQQCb4Thicrg44tn9yURoqibs7RIJx7OE
1MP7U0suEk0I+KcBgdyWgSHZ49bXM8korx2IdSqleFDMvme/baBXNv5nAkEA238a
PkZQJ2vNDTazrH4Ycha0boCnDDiFvP53trXUP53HRozA2EC+pF5oXRANzDojsSvy
ngRT6Y2dFV/qV0yOrA==
-----END PRIVATE KEY-----
公钥文件示例
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOPxXhTG5AvlVgOTZo2LfAbcuu
InguZunuq+n7ErdrFZ6L7R8bQRDwQwL4gx84HzcV/6G5XdpxQ+hkoDD3mXBHIGIN
529GZ8NogzyuY7sIUvDdNPwrLbZ1qXqn18AjO8J6rWQmYOtzbH5UwvuYu2cNh0EN
WrPcK3z5XTmJRKoxiwIDAQAB
-----END PUBLIC KEY-----
常见问题:
1、Java使用PKCS8处理后的私钥
2、Java在读取密钥时,需要去除开头为"--"的行、以及密钥的空格和换行。.NET和PHP直接使用密钥即可。
2、模板
package com.sunshine.shine.Template;
import io.jsonwebtoken.impl.TextCodec;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.crypto.Cipher;
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RsaUtil {
private static final Logger LOGGER=LoggerFactory.getLogger(RsaUtil.class);
private static final String KEY_ALGORITHM="RSA";
private static final String PRIFILENAME="rsa_private_pkcs8.pem";
private static final String PUBFILENAME="rsa_public_key.pem";
@Test
public void test(){
String str = "123456";
System.out.println("加密前:"+str);
String encrypt = encrypt(str);
System.out.println("加密后:"+encrypt);
String decrypt = decrypt(encrypt);
System.out.println("解密后:"+decrypt);
}
public static File getFile(String fn){
URL path = RsaUtil.class.getClassLoader().getResource(fn);
try {
return new File(path.toURI());
} catch (URISyntaxException e) {
LOGGER.error("密钥文件未找到");
e.printStackTrace();
}
return null;
}
/***
* 读取密钥
*/
public static String readKey(String FILENAME){
String encoding="UTF-8";
File file = getFile(FILENAME);
StringBuilder sb=new StringBuilder();
if(!(file.isFile()&&file.exists())){
LOGGER.error("密钥文件未找到");
}
try (InputStreamReader isr=new InputStreamReader(new FileInputStream(file),encoding)){
BufferedReader br=new BufferedReader(isr);
String line;
while((line = br.readLine())!=null){
if(line.startsWith("-")){
continue;
}
sb.append(line);
}
}catch (Exception e){
e.printStackTrace();
}
return sb.toString();
}
/***
* rsa加密
*/
public static String encrypt( String str){
String publicKey = readKey(PUBFILENAME);
// byte[] decoded = TextCodec.BASE64.decode(publicKey);
byte[] decoded = Base64.getDecoder().decode(publicKey);
String outStr = null;
try {
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
// outStr = TextCodec.BASE64.encode(cipher.doFinal(str.getBytes("UTF-8")));
outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8")));
} catch (Exception e) {
e.printStackTrace();
}
return outStr;
}
/***
* rsa解密
*/
public static String decrypt(String source){
if (StringUtils.isEmpty(source)){
LOGGER.debug("source不能为空");
return "";
}
StringBuilder sb=new StringBuilder();
String privateKey = readKey(PRIFILENAME);
// byte[] decode = TextCodec.BASE64.decode(privateKey);
byte[] decode = Base64.getDecoder().decode(privateKey);
try {
PrivateKey priKey = KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(decode));
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE,priKey);
// byte[] bytes = cipher.doFinal(TextCodec.BASE64.decode(source));
byte[] bytes = cipher.doFinal(Base64.getDecoder().decode(source));
String encode = new String(bytes);
sb.append(encode);
} catch (Exception e) {
LOGGER.error("密码或手机号解析错误");
e.printStackTrace();
}
return sb.toString();
}
}