本人整理網上的。好多網上的調不通。在這裏把調試好的貼出來。前端
1. 異步獲取公鑰(後臺獲取);你也能夠將公鑰串寫在頁面上;java
var publicKey = null;
$.ajax({
url: ctx+"/userLogin.do?method=getRSAPublicKey", (請求地址)
type: "post",
dataType: "text",
async:false,
success: function(data) {
if(data) publicKey = data;
}
});ajax
2. 前段加密 引入這個 jsencrypt.min.js apache
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey); // 設置公鑰
var password11 = encrypt.encrypt(password); // 加密 password 是你頁面獲取的值 password11 是加密後的值 生成隨機串安全
3. RSA 工具類 我這裏引入了 commons-codec 的依賴 1.4版本的app
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;dom
import javax.crypto.Cipher;異步
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;async
public class RSAUtils1 {
public static final String CHARSET = "UTF-8";
public static final String RSA_ALGORITHM = "RSA";
private static final KeyPair keyPair = initKey();
/**
* 初始化方法,產生key pair,提供provider和random
* @return KeyPair instance
*/
private static KeyPair initKey() {
try {
//添加provider
Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(provider);
//產生用於安全加密的隨機數
SecureRandom random = new SecureRandom();
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", provider);
generator.initialize(1024, random);
return generator.generateKeyPair();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
/**
* 產生public key
* @return public key字符串
*/
public static String generateBase64PublicKey() {
PublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
//encodeBase64(): Encodes binary data using the base64
//algorithm but does not chunk the output.
//getEncoded():返回key的原始編碼形式
return new String(Base64.encodeBase64(publicKey.getEncoded()));
}
/**
* 產生private key
*
* @return private key字符串
*/
public static String generateBase64PrivateKey(){
PrivateKey privateKey = keyPair.getPrivate();
return new String(Base64.encodeBase64(privateKey.getEncoded()));
}
/**
* 私鑰解密
* @param data
* @param privateKey
* @return
*/
public static String privateDecrypt(String data){
try{
RSAPrivateKey privateKey = getPrivateKey(generateBase64PrivateKey());
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
}catch(Exception e){
throw new RuntimeException("解密字符串[" + data + "]時遇到異常", e);
}
}
/**
* 獲得私鑰
* @param privateKey 密鑰字符串(通過base64編碼)
* @throws Exception
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//經過PKCS#8編碼的Key指令得到私鑰對象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){
int maxBlock = 0;
if(opmode == Cipher.DECRYPT_MODE){
maxBlock = keySize / 8;
}else{
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try{
while(datas.length > offSet){
if(datas.length-offSet > maxBlock){
buff = cipher.doFinal(datas, offSet, maxBlock);
}else{
buff = cipher.doFinal(datas, offSet, datas.length-offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
}catch(Exception e){
throw new RuntimeException("加解密閥值爲["+maxBlock+"]的數據時發生異常", e);
}
byte[] resultDatas = out.toByteArray();
IOUtils.closeQuietly(out);
return resultDatas;
}
public static void main(String[] args) {
// 得到公鑰 私鑰對
System.out.println("公鑰:"+generateBase64PublicKey());
System.out.println("祕鑰:"+generateBase64PrivateKey());
}
}ide
4. 給前臺返回公鑰
@RequestMapping(params = "method=getRSAPublicKey")
public void getRSAPublicKey(HttpServletRequest request,HttpServletResponse response){
PrintWriter writer;
try {
writer = response.getWriter();
String publicKey = RSAUtils1.generateBase64PublicKey();
writer.write(publicKey);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
5.解密
//先對前端密碼進行RSA解密 加到接收加密的方法中
password = password.replace(" ","+"); 加密的數據放在Url傳遞時,會將「+」變成空格,這裏變回來。
System.out.println("解密前:"+password);
password = RSAUtils1.privateDecrypt(password);
System.out.println("解密後密碼:"+password);
結束。謝謝交流評論。