生成证书
用OpenSSL工具
1.终端输入openssl,进入openssl状态
2.生成一个1024位的私钥:genrsa -out rsa_private_key.pem 1024
3.利用私钥生成JAVA支持的PKCS8类型的私钥:pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out pkcs8_private_key.pem
4.生成JAVA支持的PKCS8二进制类型的私钥:pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform DER -nocrypt -out pkcs8_private_key.der
5.生成公钥:rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
6.生成iOS支持的der证书,其间用到了证书请求和自签署根证书
6.1.创建证书请求:req -new -out cert.csr -key rsa_private_key.pem (其间会要求填写国家地区公司信息等,随便填写OR认真填写都不影响证书使用)
6.2.创建X509的自签署跟证书(iOS支持X509,有效期3650天):x509 -req -in cert.csr -out rsa_public_key.der -outform der -signkey rsa_private_key.pem -days 3650
完成了以上的步骤后应该在你所在的目录下生成了6个文件,其中pem的文件都是文本类型的,都可以使用文本编辑器或者cat命令查看。der的都是二进制的文件了,看不了。
java rsa 使用的私钥用 pkcs8_private_key.pem,公钥用 rsa_public_key.pem
接下来黏贴java RsaUtil类
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
import vpn.web.dto.enums.common.ResourceUrlEnum;
public class RsaUtil {
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
public static String PRIVATE_KEY = "";
public static String PUBLIC_KEY = "";
static {
try {
//获取私钥
InputStream is = ResourceUrlEnum.class.getClassLoader().getResourceAsStream("key/pkcs8_private_key.pem");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String s = null;
while((s = br.readLine()) != null) {
PRIVATE_KEY += s;
}
PRIVATE_KEY = PRIVATE_KEY.replace("-----BEGIN PRIVATE KEY-----", "");
PRIVATE_KEY = PRIVATE_KEY.replace("-----END PRIVATE KEY-----", "");
//获取公钥
is = ResourceUrlEnum.class.getClassLoader().getResourceAsStream("key/rsa_public_key.pem");
br = new BufferedReader(new InputStreamReader(is));
while((s = br.readLine()) != null) {
PUBLIC_KEY += s;
}
PUBLIC_KEY = PUBLIC_KEY.replace("-----BEGIN PUBLIC KEY-----", "");
PUBLIC_KEY = PUBLIC_KEY.replace("-----END PUBLIC KEY-----", "");
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取密钥对
*
* @return 密钥对
*/
public static KeyPair getKeyPair() throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(1024);
return generator.generateKeyPair();
}
/**
* 获取私钥
*
* @param privateKey
* 私钥字符串
* @return
*/
public static PrivateKey getPrivateKey(String privateKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
return keyFactory.generatePrivate(keySpec);
}
/**
* 获取公钥
*
* @param publicKey
* 公钥字符串
* @return
*/
public static PublicKey getPublicKey(String publicKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
return keyFactory.generatePublic(keySpec);
}
/**
* RSA加密
*
* @param data
* 待加密数据
* @param publicKey
* 公钥
* @return
*/
public static String encrypt(String data, PublicKey publicKey)
throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int inputLen = data.getBytes().length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offset > 0) {
if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data.getBytes(), offset,
MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data.getBytes(), offset, inputLen
- offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
// 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串
// 加密后的字符串
return new String(Base64.encodeBase64String(encryptedData));
}
/**
* RSA解密
*
* @param data
* 待解密数据
* @param privateKey
* 私钥
* @return
*/
public static String decrypt(String data, PrivateKey privateKey)
throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] dataBytes = Base64.decodeBase64(data);
int inputLen = dataBytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offset > 0) {
if (inputLen - offset > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
// 解密后的内容
return new String(decryptedData, "UTF-8");
}
/**
* 签名
*
* @param data
* 待签名数据
* @param privateKey
* 私钥
* @return 签名
*/
public static String sign(String data, PrivateKey privateKey)
throws Exception {
byte[] keyBytes = privateKey.getEncoded();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey key = keyFactory.generatePrivate(keySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(key);
signature.update(data.getBytes());
return new String(Base64.encodeBase64(signature.sign()));
}
/**
* 验签
*
* @param srcData
* 原始字符串
* @param publicKey
* 公钥
* @param sign
* 签名
* @return 是否验签通过
*/
public static boolean verify(String srcData, PublicKey publicKey,
String sign) throws Exception {
byte[] keyBytes = publicKey.getEncoded();
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initVerify(key);
signature.update(srcData.getBytes());
return signature.verify(Base64.decodeBase64(sign.getBytes()));
}
public static void main(String[] args) {
try {
// 生成密钥对
//KeyPair keyPair = getKeyPair();
//String privateKey = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded()));
//String publicKey = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded()));
String privateKey = RsaUtil.PRIVATE_KEY;
String publicKey = RsaUtil.PUBLIC_KEY;
System.out.println("私钥:" + privateKey);
System.out.println("公钥:" + publicKey);
// RSA加密
String data = "{ 'pageIndex':1, 'pageSize':5, 'token':'28450a78247e4aeabcddb53de2fe9caa', 'data':{ } }";
String encryptData = encrypt(data, getPublicKey(publicKey));
System.out.println("加密后内容:" + encryptData);
// RSA解密
String decryptData = decrypt(encryptData, getPrivateKey(privateKey));
System.out.println("解密后内容:" + decryptData);
// RSA签名
String sign = sign(data, getPrivateKey(privateKey));
// RSA验签
boolean result = verify(data, getPublicKey(publicKey), sign);
System.out.println("验签结果:" + result);
} catch (Exception e) {
e.printStackTrace();
System.out.print("加解密异常");
}
}
}
祝大家好运