百度百科:RSA公開密鑰密碼體制是一種使用不同的加密密鑰與解密密鑰,“由已知加密密鑰推導出解密密鑰在計算上是不可行的”密碼體制
RSA根據一對公鑰,私鑰對數據進行加密,簽名 ----常跟AES加密互用,AES+AESkey加密數據,RSA加密AESKey,RSA對返回報文體進行簽名
RSA加密: 拿商戶的公鑰對數據進行加密,商戶拿到數據用私鑰解密
RSA簽名:用本公司的私鑰進行簽名,商戶拿到數據用我們公司的公鑰驗籤
加解密實例 demo鏈接
-----加密方法
/**
* 使用商戶公鑰進行加密
* @param data
* @param publicKey
* @return
*/
private static String encode(String data,String publicKey){
try {
byte[] decode = Base64.decode(publicKey);
// PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(decode);
// RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(decode);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decode);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key key = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,key);
return Base64.encode(cipher.doFinal(data.getBytes("UTF-8")));
} catch (Base64DecodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return "";
}
-----解密方法
public static String decode(String data,String privateKey){
try {
byte[] dataByte = Base64.decode(data.getBytes("UTF-8"));
byte[] decode = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decode);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,rsaPrivateKey);
return new String(cipher.doFinal(dataByte));
} catch (Base64DecodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return "";
}
------測試用隨機生成 公鑰和私鑰
public static Map<String, String> keyMap = new HashMap(); //用於封裝隨機產生的公鑰與私鑰
/**
* 隨機生成密鑰對
* @throws NoSuchAlgorithmException
*/
public static void genKeyPair(){
try {
// KeyPairGenerator類用於生成公鑰和私鑰對,基於RSA算法生成對象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密鑰對生成器,密鑰大小爲96-1024位
keyPairGen.initialize(1024);
// 生成一個密鑰對,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私鑰
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公鑰
String publicKeyString = Base64.encode(publicKey.getEncoded());
System.out.println(publicKeyString);
// 得到私鑰字符串
String privateKeyString = Base64.encode((privateKey.getEncoded()));
System.out.println(privateKeyString);
// 將公鑰和私鑰保存到Map
keyMap.put("pubKey", publicKeyString); //0表示公鑰
keyMap.put("priKey", privateKeyString); //1表示私鑰
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
-----------------------簽名實例----------------
package com.fostlin.rsa;
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.DecimalFormat;
import java.util.Map;
public class RSASignUtil {
private final static String ENCODE = "UTF-8";
//RSA 簽名算法
private static final String ALGORITHM_RSA_SIGN = "SHA256WithRSA";
//密鑰算法
private static final String ALGORITHM_RSA = "RSA";
public static void main(String[] args) {
REAUtil.genKeyPair();
Map<String,String> keyMap = REAUtil.keyMap;
String sign = sign("張三",keyMap.get("priKey"),ENCODE);
System.out.println(sign);
System.out.println("校驗簽名結果:"+ doCheck("張三",sign,keyMap.get("pubKey"),ENCODE));
}
/**
* 簽名
* @param data 簽名數據
* @param privateKey 私鑰
* @param enCode 編碼
* @return
*/
public static String sign(String data,String privateKey,String enCode){
try {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey key = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance(ALGORITHM_RSA_SIGN);
signature.initSign(key);
signature.update(data.getBytes(enCode));
return Base64.encode(signature.sign());
} catch (Base64DecodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
/**
* 驗籤
* @param content 數據
* @param sign 簽名
* @param publicKey 公鑰
* @param encode 編碼
* @return
*/
public static boolean doCheck(String content, String sign, String publicKey,String encode){
try {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey1 = keyFactory.generatePublic(x509EncodedKeySpec);
Signature signature = Signature.getInstance(ALGORITHM_RSA_SIGN);
signature.initVerify(publicKey1);
signature.update(content.getBytes(encode));
return signature.verify(Base64.decode(sign));
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}