package com.okni.okpool.okfinance.util;
import jodd.util.Base64;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
/**
* 创建人:kerns
* 创建时间: 2019/7/17 2:51 PM
**/
public class RSACrypto {
private final static String RSA = "RSA";
public static PublicKey uk;
public static PrivateKey rk;
public static void generateKey() throws Exception{
KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA);
gen.initialize(1024, new SecureRandom());
KeyPair keyPair = gen.generateKeyPair();
uk = keyPair.getPublic();
System.out.println("公钥===="+uk.getFormat());
rk = keyPair.getPrivate();
System.out.println("私钥===="+rk.toString());
System.out.println("公钥:"+new BASE64Encoder().encodeBuffer(uk.getEncoded()));
System.out.println("私钥:"+new BASE64Encoder().encodeBuffer(rk.getEncoded()));
}
private static byte[] encrypt(String text, PublicKey pubRSA) throws Exception{
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubRSA);
return cipher.doFinal(text.getBytes());
}
public final static String encrypt(String text){
try {
return byte2hex(encrypt(text, uk));
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
public final static String decrypt(String data){
try{
return new String(decrypt(hex2byte(data.getBytes())));
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
private static byte[] decrypt(byte[] src) throws Exception{
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, rk);
return cipher.doFinal(src);
}
public static String byte2hex(byte[] b){
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n ++)
{
stmp = Integer.toHexString(b[n] & 0xFF);
if (stmp.length() == 1)
hs += ("0" + stmp);
else
hs += stmp;
}
return hs.toUpperCase();
}
public static byte[] hex2byte(byte[] b){
if ((b.length % 2) != 0)
throw new IllegalArgumentException("长度不是偶数");
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2)
{
String item = new String(b, n, 2);
b2[n/2] = (byte)Integer.parseInt(item, 16);
}
return b2;
}
/**
* 签名
*
* @return 签名后经过base64处理的字符串
* @throws Exception
*/
public static String sign(String str) {
String base64Sign = "";
try {
// 签名
Signature sign = Signature.getInstance("SHA1withRSA");
sign.initSign(rk);
byte[] bysData = str.getBytes("UTF-8");
sign.update(bysData);
byte[] signByte = sign.sign();
BASE64Encoder encoder = new BASE64Encoder();
base64Sign = encoder.encode(signByte);
} catch (Exception e) {
e.printStackTrace();
}
return base64Sign;
}
/**
* 数据验证
*
* @param signStr 加密后的数据
* @param verStr 原始字符
* @return
*/
public static boolean verify(String signStr, String verStr){
boolean verfy = false;
try {
BASE64Decoder decoder = new BASE64Decoder();
byte[] signed = decoder.decodeBuffer(signStr);
Signature sign = Signature.getInstance("SHA1withRSA");
sign.initVerify(uk);
sign.update(verStr.getBytes("UTF-8"));
verfy = sign.verify(signed);
} catch (Exception e) {
e.printStackTrace();
}
return verfy;
}
/**
* 使用私钥对数据进行加密签名
* @param data 数据
* @param privateKeyString 私钥
* @return 加密后的签名
*/
public static String sign(String data, String privateKeyString) throws Exception {
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(privateKeyString)));
java.security.Signature signet = java.security.Signature.getInstance("SHA1withRSA");
signet.initSign(privateKey);
signet.update(data.getBytes("utf-8"));
byte[] signed = signet.sign();
return Base64.encodeToString(signed);
}
/**
* 使用公钥判断签名是否与数据匹配
* @param data 数据
* @param sign 签名
* @param publicKeyString 公钥
* @return 是否篡改了数据
*/
public static boolean verify(String data, String sign, String publicKeyString) throws Exception {
KeyFactory keyf = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyf.generatePublic(new X509EncodedKeySpec(Base64.decode(publicKeyString)));
java.security.Signature signet = java.security.Signature.getInstance("SHA1withRSA");
signet.initVerify(publicKey);
signet.update(data.getBytes("utf-8"));
return signet.verify(Base64.decode(sign));
}
//just for test
public static void main(String args[]){
try{
// RSACrypto.generateKey();
// String cc="mnn123456";
// String md5datas="mnn123456";// Md5Utils.getMD5(cc,"UTF-8");
// System.out.println("MD5:"+md5datas);
// String cipherText = RSACrypto.encrypt(md5datas);
// System.out.println("密文是:"+cipherText);
// String plainText = RSACrypto.decrypt(cipherText);
// System.out.println("明文是:"+plainText);
// String signData = RSACrypto.sign(md5datas);
// System.out.println("签名:"+signData);
// boolean flag = RSACrypto.verify(signData, md5datas);
// System.out.println("校验:"+flag);
//私钥
String privateKeyString = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANjUPqvutSFTALjOpgjN27bXL8oYY6UKjqNetcaBf1nbnVczPenH2BMehN5iq+ibYf/PgwuMbKIoBGxTEIvqdm3jAvcaqMYkWQwVW+NQ4AO7bR4IGAcdZXMpnaoS03yeoUC4jm/6nKfv10SL3bnZpZamznY3eAC5MGsYwzg+D0gzAgMBAAECgYBCS7LV0uiixcQkvVpausaBAw5jlk1xOucd4GlnxlRv3wwei1ZU0nuobN5nOHgjaM7v7jy9HTRh6CZiEIuwnAGVSx1+91K042rraLhQ9iomRqxZqymPAF6o+g+QhlPbjC62j1eeJvFivcwzpdH7SPdjdFpmDX31VYx01HyFYSEqwQJBAP7R7U3S/BduCS6kjEVry2B5u/l597Jr9Eut0M/D7zbJgREgCi1OiF1V3c34cnBQhRuhhojD3pm9q/3s9WNn0ZECQQDZ1Ugvsqc/b4lBYFDa6uaoIjboLB/MGZi3Pr58Q/xMZa1vZQbYeiCAqJQsBvEPnM/HC2HL7zKcHc8C505BKNuDAkEA3QgdDkd3sZ8ZyeKjZcgl5m5Rtgms6JApnMeNe9qaEezhzof7K+eV81f7CKF8Kp49h4UpnFJCMRtMJ/s1s18ncQJBAJIMcc2pFoFtorT2gr+EZwmrhuy7SMZrEv0pUEW4v1vpgBMDxUc2+rvISzAJp240UQq/Et7MjT4mrjjgJJODdUkCQBeydFAFY8LpQkxOStq7+avjgDpZ8wFc6dFEgS/mLbQPERBlYoW/+epGdUdZPYCWv252hf5MIadwM5a3TQvtDcA=";
//公钥
String publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY1D6r7rUhUwC4zqYIzdu21y/KGGOlCo6jXrXGgX9Z251XMz3px9gTHoTeYqvom2H/z4MLjGyiKARsUxCL6nZt4wL3GqjGJFkMFVvjUOADu20eCBgHHWVzKZ2qEtN8nqFAuI5v+pyn79dEi9252aWWps52N3gAuTBrGMM4Pg9IMwIDAQAB";
//私钥
// String privateKeyString =new BASE64Encoder().encodeBuffer(rk.getEncoded());
// //公钥
// String publicKeyString =new BASE64Encoder().encodeBuffer(uk.getEncoded());
System.out.println("公钥:"+publicKeyString);
System.out.println("私钥:"+privateKeyString);
String data = "mnn123456";
String s = sign(data, privateKeyString.replace("\n",""));
System.out.println("针对数据[" + data + "]签名: " + s);
// data = "mnn123456";
//String s="ER4w5KXI/JrhQ7l8No4iTlNuewhaa8bWRpu4jVJq/P7Wz6qiTRXfqETrGg4/NHO/dVi45ZsK5p3kk8hPue95HBj8bUSEd0eJ2TePOfiZrJwPWVxO+B4K9SvtpJhKiDQA9K+cuPCLQWWglJ3SkkNozf1h4N6W8rz4jRspwEdRQcA=";
System.out.println("签名验证结果:" + verify(data, s, publicKeyString.replace("\n","")));
}
catch(Exception e)
{
e.printStackTrace();
}
}
}