一、RSA简介
RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
二、加密和签名的区别
加密和签名都是为 了安全性考虑的,简单的说,加密是为了防止消息泄露,而签名是为了防止消息被篡改。
如上图所示,A系统需要发送信息到B系统,这个过程需要采用RSA非对称加密算法防止信息泄漏和 篡改。首先A、B首先都需要获得各自的一对秘钥(公钥和私钥),然后具体的操作过程如上图文字。
如果我们在实际应用中如果只使用加密和签名中的一种可能带来不同的问题。如果我们在消息传递的过程中只对数据加密不进行签名,这样虽然可保证被截获的消息 不会泄露,但是可以利用截获的公钥,将假信息进行加密,然后传递到B。如果只对信息签名,这样虽然可以防止消息被篡改,但是不能防止消息泄露,所以我们在实际项目中需要根据实际需求进行使用。
总结:公钥加密、私钥解密、私钥签名、公钥验签。
三、java代码工具类
3.1 RSA工具类RSAUtil
package com.jack.common.utils;
import java.io.*;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
/**
* <p>
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
* </p>
*
*/
public class RSAUtil {
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
private static final int MAX_ENCRYPT_BLOCK = 117;
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* method will close inputSteam
*
* @param pemFileInputStream
* @return
*/
public static PublicKey loadPublicKey(InputStream pemFileInputStream) {
return readPublicKey(readPEMFile(pemFileInputStream));
}
/**
* method will close inputSteam
*
* @param pkcs8PemFileInputStream
* @return
*/
public static PrivateKey loadPrivateKey(InputStream pkcs8PemFileInputStream) {
return readPrivateKey(readPEMFile(pkcs8PemFileInputStream));
}
/**
*
* @param pemFile
* @return
*/
public static PublicKey loadPublicKey(String pemFile) {
return readPublicKey(readPEMFile(pemFile));
}
/**
*
* @param pkcs8PemFile
* @return
*/
public static PrivateKey loadPrivateKey(String pkcs8PemFile) {
return readPrivateKey(readPEMFile(pkcs8PemFile));
}
/**
* read pem file, delete first and last line, sth. like:<br />
* <p>
* -----BEGIN PUBLIC KEY----- -----END PUBLIC KEY-----
* </p>
*
* @param filename
* @return
*/
public static String readPEMFile(String filename) {
try {
return readPEMFile(new FileInputStream(filename));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* method will close inputSteam
*
* @param stream
* pem file inputstream
* @return
*/
public static String readPEMFile(InputStream stream) {
if (null != stream) {
BufferedReader in = null;
StringBuilder ret = new StringBuilder();
String line;
try {
in = new BufferedReader(new InputStreamReader(stream, "ASCII"));
line = in.readLine();
while (null != line) {
if (!(line.startsWith("-----BEGIN ") || line.startsWith("-----END "))) {
ret.append(line);
ret.append("\n");
}
line = in.readLine();
}
return ret.toString();
} catch (Exception ex) {
throw new RuntimeException(ex);
} finally {
try {
stream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
if (null != in) {
try {
in.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
return null;
}
/**
*
* @param pkcs8Base64String
*