import org.junit.Test;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;
/**
* @author EvanY
* @since 2021/11/30
*/
public class RSAUtils {
private static final String RSA = "RSA";
private static final String RSA_ECB_PKCS1 = "RSA/ECB/PKCS1Padding";
private static final String SHA1withDSA = "SHA1withDSA";
private static final String SHA1withRSA = "SHA1withRSA";
private static final String SHA256withRSA = "SHA256withRSA";
private static final int BYTE_BIT_LENGTH = 8;
private static final int PKCS1_PADDING_LENGTH = 11;
String privateKeyStr = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAI++rMw5U/7DFooAlSZ9V2l89l44KfjClCFFFxzfLGvhVDTduP9FI8gQyOOvNekipcw1E01XbV6/JhGoKuwHVFfmCFeZWTBBJhMdIb4qh2cNOgfR5yEIxrn0928VnA+RwLg/LEtXuo0pkSs/SQ4Ey62QTGanWP0B5bRWkhxGIHTvAgMBAAECgYBWXxkPYYcR9oFNjMoSJZBnhzm2JYM6wRgm4Y/gvky/ydZCKdQmNpIofcVn4fi/zBzZli6x8015d9vVEjowNrs7YmmiAWK6BeF50Jo9a/6b42DCmYnJd4hLSzmXtlNI6nwvJ72vzCSOqji5Bzrg6Gj5MFHmeHyLZtqUhtu8nmpD8QJBAPx4NJjgLNwdCHZ1avKcmRFAHdnkc2DDYIWyi2SqI7wX/+pk6ExwT/wOC5a/8bl+hJcwLQNTXTVybOENV4sZfmcCQQCRwUFIdY8BLzDm6joLmaXXVTGPwlNc49IsSMcCd3YyAQtB6giIZeUpxYrBQlwrnd17f68ny7BNSSnlgHs0QDA5AkEAl1+DOb3/Z6JItq3EB974r60fuMsOmo/KSZ85kIuqjVZebK0/0sTsUBYjwKkpR6yh1vxdoMbU9fy7Z1xWhuIsNQJBAIdsElbbexnzmbECsRm0EUUnz5utRr0Io28n01e0XOoK1EXSx0jLu4b7FneHS5Hu5Cjpsnj8JHs6XiXxIQekF+kCQQD0u19/Pv2aZ4q2MBAwI2X5sElSfUEr3WNRFgKzxvejjgtxcAgK/UJCqBkcab/bDE5tHL64hljCo+kdZS0829C3";
String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPvqzMOVP+wxaKAJUmfVdpfPZeOCn4wpQhRRcc3yxr4VQ03bj/RSPIEMjjrzXpIqXMNRNNV21evyYRqCrsB1RX5ghXmVkwQSYTHSG+KodnDToH0echCMa59PdvFZwPkcC4PyxLV7qNKZErP0kOBMutkExmp1j9AeW0VpIcRiB07wIDAQAB";
public static String encodeToString(byte[] unEncoded) {
return new String(encode(unEncoded), StandardCharsets.UTF_8);
}
public static byte[] encode(byte[] unEncoded) {
return Base64.getEncoder().encode(unEncoded);
}
public static byte[] decodeFromString(String encoded) {
return Base64.getDecoder().decode(encoded.getBytes(StandardCharsets.UTF_8));
}
/**
* 根据公钥字符串生成公钥对象
*/
public static PublicKey getPublicKey(String publicKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] keyByte = decodeFromString(publicKeyStr);
return KeyFactory.getInstance(RSA).generatePublic(new X509EncodedKeySpec(keyByte));
}
/**
* 根据私钥字符串生成私钥对象
*/
public static PrivateKey getPrivateKey(String privateKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] keyByte = decodeFromString(privateKeyStr);
return KeyFactory.getInstance(RSA).generatePrivate(new PKCS8EncodedKeySpec(keyByte));
}
/**
* 用公钥加密字符串
*/
public static String encrypt(String algorithm, String publicKeyStr, String unencryptedStr) throws Exception {
return encrypt(algorithm, publicKeyStr, null, StandardCharsets.UTF_8, unencryptedStr);
}
public static String encrypt(String algorithm, String publicKeyStr, AlgorithmParameterSpec param, Charset charset, String unencryptedStr) throws Exception {
PublicKey publicKey = getPublicKey(publicKeyStr);
Cipher cipher = initCipher(algorithm, Cipher.ENCRYPT_MODE, publicKey, param);
byte[] bytes = unencryptedStr.getBytes(charset);
//单次加密最大长度
int maxEncryptByteLength = ((RSAKey) publicKey).getModulus().bitLength() / BYTE_BIT_LENGTH;
int excludePaddingMaxLength = maxEncryptByteLength - PKCS1_PADDING_LENGTH;
int encryptCount = bytes.length / excludePaddingMaxLength;
//可能有剩余字符串,不足一次加密长度,
int outSize = maxEncryptByteLength * (encryptCount + 1);
byte[] encryptedBytes = getBytes(cipher, bytes, excludePaddingMaxLength, outSize);
return encodeToString(encryptedBytes);
}
private static byte[] getBytes(Cipher cipher, byte[] bytes, int step, int outSize) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(outSize);
int offset = 0;
byte[] outBytes;
while (offset + step <= bytes.length) {
outBytes = cipher.doFinal(bytes, offset, step);
out.write(outBytes);
offset += step;
}
if (offset < bytes.length) {
outBytes = cipher.doFinal(bytes, offset, bytes.length - offset);
out.write(outBytes);
}
return out.toByteArray();
}
/**
* 用私钥解密字符串
*/
public static String decrypt(String algorithm, String privateKeyStr, String encryptedStr) throws Exception {
return decrypt(algorithm, privateKeyStr, null, StandardCharsets.UTF_8, encryptedStr);
}
public static String decrypt(String algorithm, String privateKeyStr, AlgorithmParameterSpec param, Charset charset, String encryptedStr) throws Exception {
PrivateKey privateKey = getPrivateKey(privateKeyStr);
Cipher cipher = initCipher(algorithm, Cipher.DECRYPT_MODE, privateKey, param);
byte[] bytes = decodeFromString(encryptedStr);
//单次解密最大长度
int maxDecryptByteLength = ((RSAKey) privateKey).getModulus().bitLength() / BYTE_BIT_LENGTH;
int excludePaddingMaxLength = maxDecryptByteLength - PKCS1_PADDING_LENGTH;
int decryptCount = bytes.length / maxDecryptByteLength;
int outSize = decryptCount * excludePaddingMaxLength;
byte[] decryptedBytes = getBytes(cipher, bytes, maxDecryptByteLength, outSize);
return new String(decryptedBytes, charset);
}
/**
* 初始化密码
*/
public static Cipher initCipher(String algorithm, int cipherMode, Key key, AlgorithmParameterSpec param)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException {
Cipher cipher = Cipher.getInstance(algorithm);
if (param == null) {
cipher.init(cipherMode, key);
} else {
cipher.init(cipherMode, key, param);
}
return cipher;
}
//签名
public static String sign(String algorithm, String privateKeyStr, Charset charset, String encryptedStr) throws Exception {
PrivateKey privateKey = getPrivateKey(privateKeyStr);
Signature signature = Signature.getInstance(algorithm);
signature.initSign(privateKey);
signature.update(encryptedStr.getBytes(charset));
byte[] signByte = signature.sign();
return encodeToString(signByte);
}
public static boolean verifySign(String algorithm, String publicKeyStr, Charset charset, String encryptedStr, String signStr) throws Exception {
PublicKey publicKey = getPublicKey(publicKeyStr);
Signature signature = Signature.getInstance(algorithm);
signature.initVerify(publicKey);
signature.update(encryptedStr.getBytes(charset));
byte[] signByte = decodeFromString(signStr);
return signature.verify(signByte);
}
public static String[] generateKeys(String algorithm, int keySize) throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
keyPairGenerator.initialize(keySize);
KeyPair keyPair = keyPairGenerator.genKeyPair();
byte[] privateKeyByte = keyPair.getPrivate().getEncoded();
byte[] publicKeyByte = keyPair.getPublic().getEncoded();
return new String[]{new String(encode(privateKeyByte)), new String(encode(publicKeyByte))};
}
@Test
public void test() throws NoSuchAlgorithmException {
String[] keys = generateKeys(RSA, 512);
System.out.println(keys[0]);
System.out.println(keys[1]);
}
@Test
public void testEncrypt() throws Exception {
String[] keys = generateKeys(RSA, 1024);
System.out.println("PrivateKeyStr:" + keys[0]);
System.out.println("PublicKeyStr:" + keys[1]);
String unencryptedStr = "{\"serialNo\":\"中国China
标签:Java,String,java,int,加解密,RSA,static,import,byte
From: https://www.cnblogs.com/yy299/p/18031198