package com.gzxf.utils;
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.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
@SuppressWarnings("restriction")
public class RSAHelper {
public static int keySize = 2048;
public static String charset = "UTF-8";
public static byte[] toByteArray(String hexString) {
if (hexString == null || hexString.isEmpty())
return null;
hexString = hexString.toLowerCase();
final byte[] byteArray = new byte[hexString.length() >> 1];
int index = 0;
for (int i = 0; i < hexString.length(); i++) {
if (index > hexString.length() - 1)
return byteArray;
byte highDit = (byte) (Character.digit(hexString.charAt(index), 16) & 0xFF);
byte lowDit = (byte) (Character.digit(hexString.charAt(index + 1), 16) & 0xFF);
byteArray[i] = (byte) (highDit << 4 | lowDit);
index += 2;
}
return byteArray;
}
public static String toHexString(byte[] byteArray) {
final StringBuilder hexString = new StringBuilder("");
if (byteArray == null || byteArray.length <= 0)
return null;
for (int i = 0; i < byteArray.length; i++) {
int v = byteArray[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
hexString.append(0);
}
hexString.append(hv);
}
return hexString.toString().toLowerCase();
}
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = toByteArray(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = toByteArray(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
public static String getKeyString(Key key) throws Exception {
byte[] keyBytes = key.getEncoded();
String s = toHexString(keyBytes);
return s;
}
public static byte[] byteMerger(byte[] bt1, byte[] bt2) {
if(bt2 == null) return bt1;
if(bt1 == null) return bt2;
byte[] bt3 = new byte[bt1.length+bt2.length];
System.arraycopy(bt1, 0, bt3, 0, bt1.length);
System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
return bt3;
}
public static byte[] subArray(byte[] byte_array, int off, int len) {
byte[] result = new byte[len];
System.arraycopy(byte_array, off, result, 0, len);
return result;
}
public static byte[] encryptFinal(byte[] src, Cipher cipher) throws Exception {
byte[] enBytes = null;
int len = src.length;
int limit = keySize / 8 - 11;
if (len > limit) {
int remainder = len % limit;
int divisor = len / limit;
for (int i = 0; i < divisor; i++) {
byte[] subEnBytes = cipher.doFinal(src, limit * i, limit);
enBytes = byteMerger(enBytes, subEnBytes);
}
if (remainder > 0) {
byte[] subEnBytes = cipher.doFinal(src, limit * divisor,
remainder);
enBytes = byteMerger(enBytes, subEnBytes);
}
} else {
enBytes = cipher.doFinal(src);
}
return enBytes;
}
private static byte[] decryptFinal(byte[] src, Cipher cipher) throws Exception {
byte[] deBytes = null;
int len = src.length;
int limit = keySize / 8;
if (len > limit) {
int remainder = len % limit;
int divisor = len / limit;
for (int i = 0; i < divisor; i++) {
byte[] subDeBytes = subArray(src, limit * i, limit);
deBytes = byteMerger(deBytes, cipher.doFinal(subDeBytes));
}
if (remainder > 0) {
byte[] subDeBytes = subArray(src, limit * divisor, remainder);
deBytes = byteMerger(deBytes, cipher.doFinal(subDeBytes));
}
} else {
deBytes = cipher.doFinal(src);
}
if (true) {
byte[] deBytesWithOutZero = null;
for (int i = 0; i < deBytes.length; i++) {
if (deBytes[i] == (byte) 0) {
continue;
} else {
byte[] cur = new byte[1];
cur[0] = deBytes[i];
deBytesWithOutZero = byteMerger(deBytesWithOutZero, cur);
}
}
return deBytesWithOutZero;
}
return deBytes;
}
public static void main(String[] args) throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(RSAHelper.keySize);
KeyPair keyPair = keyPairGen.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String publicKeyString = getKeyString(publicKey);
System.out.println("public:\n" + publicKeyString);
String privateKeyString = getKeyString(privateKey);
System.out.println("private:\n" + privateKeyString);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
String strPlainText = "我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!";
strPlainText += "我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!我们都很好!";
strPlainText += "OK!";
byte[] plainText = strPlainText.getBytes(charset);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] enBytes = encryptFinal(plainText, cipher);
System.out.println("plainText:" + strPlainText);
System.out.println("plainHex:" + toHexString(plainText));
System.out.println("enBYTES:" + new String(enBytes));
System.out.println("enHEX:" + toHexString(enBytes));
publicKey = getPublicKey(publicKeyString);
privateKey = getPrivateKey(privateKeyString);
String hexStr = toHexString(enBytes);
byte[] gotEnBytes = toByteArray(hexStr);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] deBytes = decryptFinal(gotEnBytes, cipher);
publicKeyString = getKeyString(publicKey);
System.out.println("public:\n" + publicKeyString);
privateKeyString = getKeyString(privateKey);
System.out.println("private:\n" + privateKeyString);
String s = new String(deBytes, charset);
System.out.println(s);
}
}