package com.mollen.utils;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.Key;
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.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
/**
* RSA加密方式实现信息交换.
*
* @author 阔皮大师
* @created 2022-04-23
*/
public class RsaUtils {
/**
* RSA algorithm: RSA算法.
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* digital signature algorithm: 签名方式.
*/
public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
/**
* RSA maximum encryption text size: 最大加密文本大小.
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA maximum decryption text size: 最大解密文本大小.
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 签名
*
* @param data 明文
* @param privateKey 私钥
* @return byte[]
*/
public static byte[] sign(byte[] data, String privateKey) {
try {
byte[] keyBytes = Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return signature.sign();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 验签
*
* @param data 明文
* @param publicKey 公钥
* @param sign 密文
* @return boolean
*/
public static boolean verify(byte[] data, String publicKey, byte[] sign) {
try {
byte[] keyBytes = Base64.getDecoder().decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(sign);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 通过公钥加密
*
* @param data 明文
* @param publicKey 公钥
* @return byte[]
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) {
try {
byte[] keyBytes = Base64.getDecoder().decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
return getBytes(data, cipher, MAX_ENCRYPT_BLOCK);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 通过私钥解密
*
* @param encryptedData 密文
* @param privateKey 私钥
* @return byte[]
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) {
try {
byte[] keyBytes = Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
return getBytes(encryptedData, cipher, MAX_DECRYPT_BLOCK);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* getBytes
*
* @param contentData
* @param cipher
* @param maxBlockSize
* @return byte[]
* @throws Exception
*/
private static byte[] getBytes(byte[] contentData, Cipher cipher, int maxBlockSize) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int inputLen = contentData.length;
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段 加密/解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > maxBlockSize) {
cache = cipher.doFinal(contentData, offSet, maxBlockSize);
}
else {
cache = cipher.doFinal(contentData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * maxBlockSize;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* 生成一对密钥
*
* @return Map<String,String> 密钥
*/
public static Map<String,String> getGeneraKey(){
try{
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
byte[] publicKey = keyPair.getPublic().getEncoded();
byte[] privateKey = keyPair.getPrivate().getEncoded();
String publicKe = Base64.getEncoder().encodeToString(publicKey);
String privateKe = Base64.getEncoder().encodeToString(privateKey);
Map keyMap = new HashMap(2);
System.out.println("--------Generate secret key------");
System.out.println("|-- publicKey: " + publicKe);
System.out.println("|-- privateKey: " + privateKe);
System.out.println("---------------------------------");
keyMap.put("rsa_pub", publicKe);
keyMap.put("rsa", privateKe);
return keyMap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.mollen.utils;
import java.util.Base64;
import java.util.Map;
/**
* RsaTest.
*
* @author 阔皮大师.
* @created 2022-04-23 14:07
*/
public class RsaTest {
public static void main(String[] args) {
// 生成秘钥
Map<String, String> generaKey = RsaUtils.getGeneraKey();
String privateKey = generaKey.get("rsa");
String publicKey = generaKey.get("rsa_pub");
String message = "My public key:" + publicKey ;
byte[] deMessage = Base64.getEncoder().encode(message.getBytes());
// 签名、验签
byte[] sign = RsaUtils.sign(deMessage, privateKey);
boolean verify = RsaUtils.verify(deMessage, publicKey, sign);
// 签名合法性校验
System.out.println("|-- Response message:" + verify);
// 原始密码
String password = "Test_123";
System.out.println("|-- Resource password:" + password);
// Base64编码、RSA加密
byte[] encode = Base64.getEncoder().encode(password.getBytes());
// 公钥加密、私钥解密
byte[] encryptData = RsaUtils.encryptByPublicKey(encode, publicKey);
byte[] decryptData = RsaUtils.decryptByPrivateKey(encryptData, privateKey);
// RSA解密、Base64解码
byte[] decode = Base64.getDecoder().decode(decryptData);
// 解密密码
System.out.println("|-- PassWord: " + new String(decode));
}
}