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.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
/**
* 非對稱加密算法RSA算法元件
* 非對稱算法一般是用來傳送對稱加密算法的密鑰來使用的,相對于DH算法,RSA算法隻需要一方構造密鑰,不需要
* 大費周章的構造各自本地的密鑰對了。DH算法隻能算法非對稱算法的底層實作。而RSA算法算法實作起來較為簡單
* @author 張昭
* @time 2018/12/25 20:31
*/
public class RSASecurityUtil {
static final String ALGORITHM_RSA = "RSA";
static final String ALGORITHM_SIGN = "MD5withRSA";
static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMhoJ/mBHbkDRi+mVwUU7MXyJ5kZx+esx6WyfPIixcK5Z7sCDaoLve5pb1EHpsAq0oI2OlRqh+M44LfUD1GYYRHMzXwYTSeDDcyKjZc+zvsNfWf64h0Ne51BxBvc0DQjW2g6rwBBgu06mYHnsIxskXLTsY4b2npXwFtKmqQaIadQIDAQAB";
static final String privteKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIyGgn+YEduQNGL6ZXBRTsxfInmRnH56zHpbJ88iLFwrlnuwINqgu97mlvUQemwCrSgjY6VGqH4zjgt9QPUZhhEczNfBhNJ4MNzIqNlz7O+w19Z/riHQ17nUHEG9zQNCNbaDqvAEGC7TqZgeewjGyRctOxjhvaelfAW0qapBohp1AgMBAAECgYBm5qBsunhpJSGXUPAy3PcspIVkLAJCg71z44g1HzsIi0p4bDLCpWys/oGQFm7u5M7TU4bGIgWD1FCxjRih4fzPN0yOvFgoyvPj8HmX6DzhD5GsgixTWTWEHBU9/sL1N1NgCSIXmMufRg005CD+/G2TnLezo4KVbwkFwb+JHdpaAQJBANYVNwzEMblHsFK/Bl7EIh3NsSHCgpTCzUr5PC5kc8Ra/1hTVYem9u63Ospr2dgTJEexC+tXjjWrK20sOgF03MECQQCoCkTPY00TCsPnTgkOthAXrpiHFlJLC6rA4pz71M6jpq0S5ir90T+nACeHWGMmKiS6vUUjbldknynVQxB6tYa1AkBPxgYGbtFsjkco/l+8Tm+8FVrNDrMkBdcD+g2v5+SvpY0C98KmUtQvLf3tUfUSLEfXoySi5LRsUUVUYCeZRVfBAkEAh9iNWi8H3w4D45lFXzw19D80lXipHHwZFYfdqwSV7NzQ7Adg2AJyd9p7GkKNHQxS1xgtrYAFbJXzZrGpv9nCRQJBAL8BKOhwEpvfQQmyriYhlfbHkUNYDgBQn/oqvY4WKkVAo6+h7rU6vwcWDWbzEKz/tlfjM0MbvHmTnhQlUexsKu4=";
public static void main(String[] args) throws Exception {
// 公鑰加密
String a = "admin阿斯頓發生發生";
String target = encrypt(a, publicKey);
// 私鑰解密
String sourc2e = decrypt(target, privteKey);
System.out.println("t, 公鑰加密後的資料: " + target);
System.out.println("t, 私鑰解密後的資料: " + sourc2e);
/*System.out.println("--------------------------私鑰加密并且簽名,公鑰驗證簽名并且解密------------------------------");
// 私鑰加密
target = encryptionByPrivateKey(source, priKey);
// 簽名
String sign = signByPrivateKey(target, priKey);
// 驗證簽名
verifyByPublicKey(target, sign, pubKey);
// 公鑰解密
decryptionByPublicKey(target,pubKey);*/
}
/**
* 生成密鑰對
* @throws Exception
*/
static void generatorKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
keyPairGen.initialize(1024);//可以更改1024,但是要是512的倍數,
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
byte[] keyBs = rsaPublicKey.getEncoded();
String publicKey = encodeBase64(keyBs);
System.out.println("生成的公鑰:\r\n" + publicKey);
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
keyBs = rsaPrivateKey.getEncoded();
String privateKey = encodeBase64(keyBs);
System.out.println("生成的私鑰:\r\n" + privateKey);
}
/**
* 擷取公鑰
* @return
* @throws Exception
*/
static PublicKey getPublicKey(String publicKey) throws Exception {
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(decodeBase64(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
return keyFactory.generatePublic(publicKeySpec);
}
/**
* 擷取私鑰
* @return
* @throws Exception
*/
static PrivateKey getPrivateKey(String privateKey) throws Exception {
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(decodeBase64(privateKey));
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
return keyFactory.generatePrivate(privateKeySpec);
}
/**
* 公鑰加密
* @param source
* @return
* @throws Exception
*/
public static String encrypt(String source, String pubKey) throws Exception{
PublicKey publicKey = getPublicKey(pubKey);
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipher.update(source.getBytes("UTF-8"));
return encodeBase64(cipher.doFinal());
}
/**
* 公鑰解密
* @param target
* @throws Exception
*/
static void decryptionByPublicKey(String target, String pubKey) throws Exception{
PublicKey publicKey = getPublicKey(pubKey);
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
cipher.update(decodeBase64(target));
String source = new String(cipher.doFinal(), "UTF-8");
System.out.println("公鑰解密後的資料:\r\n" + source);
}
/**
* 公鑰驗證簽名
* @return
* @throws Exception
*/
static void verifyByPublicKey(String target, String sign, String pubKey) throws Exception{
PublicKey publicKey = getPublicKey(pubKey);
Signature signature = Signature.getInstance(ALGORITHM_SIGN);
signature.initVerify(publicKey);
signature.update(target.getBytes("UTF-8"));
if (signature.verify(decodeBase64(sign))) {
System.out.println("簽名正确!");
} else {
System.out.println("簽名錯誤!");
}
}
/**
* 私鑰加密
* @param source
* @return
* @throws Exception
*/
static String encryptionByPrivateKey(String source, String priKey) throws Exception {
PrivateKey privateKey = getPrivateKey(priKey);
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
cipher.update(source.getBytes("UTF-8"));
String target = encodeBase64(cipher.doFinal());
System.out.println("私鑰加密後的資料:\r\n" + target);
return target;
}
/**
* 私鑰解密
* @param target
* @throws Exception
*/
public static String decrypt(String target, String priKey) throws Exception {
PrivateKey privateKey = getPrivateKey(priKey);
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
cipher.update(decodeBase64(target));
return new String(cipher.doFinal(), "UTF-8");
}
/**
* 私鑰簽名
* @param target
* @return
* @throws Exception
*/
static String signByPrivateKey(String target, String priKey) throws Exception{
PrivateKey privateKey = getPrivateKey(priKey);
Signature signature = Signature.getInstance(ALGORITHM_SIGN);
signature.initSign(privateKey);
signature.update(target.getBytes("UTF-8"));
String sign = encodeBase64(signature.sign());
System.out.println("生成的簽名:\r\n" + sign);
return sign;
}
/**
* base64編碼
* @param source
* @return
* @throws Exception
*/
static String encodeBase64(byte[] source) throws Exception{
return new String(Base64.encodeBase64(source), "UTF-8");
}
/**
* Base64解碼
* @param target
* @return
* @throws Exception
*/
static byte[] decodeBase64(String target) throws Exception{
return Base64.decodeBase64(target.getBytes("UTF-8"));
}
}