非对称加密就是加密和解密使用的不是一个密钥,使用的是公钥+私钥,一个加密,另外一个解密,一般都是私钥加密,公钥解密
首先使用keypair获取我们的公钥和私钥,配对获取,获取的秘钥可以直接是对象,也可以获取字节数组
如果我们使用现有的公钥和私钥,需要使用keyfacktory来讲秘钥转换为响应的对象,使用对象生成密码器,使用密码器进行对数据的加密
下面例子是使用私钥加密公钥解密,如果是公钥加密私钥解密,需要将 字符串与字节数组的转换互换位置
public class AsymmetricEncoder {
public static void main(String[] args) throws Exception {
KeyPair keyPair = getKeyPair();
String s = cryptoByPrivate(1, keyPair.getPrivate().getEncoded(), "床前明月光,疑是地上霜,举头望明月,低头思故乡");
System.out.println(s);
String s1 = cryptoByPublic(2, keyPair.getPublic().getEncoded(), s);
System.out.println(s1);
}
/**
* 使用公钥加密字符串
*
* @param f 1:加密 2:解密
* @param key 公钥
* @param str 字符串
* @return
* @throws Exception
*/
public static String cryptoByPublic(int f, byte[] key, String str) throws Exception {
// 密码器 加密器
Cipher cipher = Cipher.getInstance("RSA");
// 2: 解密
// getPubKey(key): 公钥key获取公钥对象
cipher.init(f, (RSAPublicKey) getPubKey(key));
// 加密
byte[] b2 = cipher.doFinal(hexStringToBytes(str));
// 解密的内容
return new String(b2, "utf-8");
}
/**
* 私钥加密字符串
*
* @param f 1:加密 2:解密
* @param key 私钥
* @param str 字符串
* @throws Exception
*/
public static String cryptoByPrivate(int f, byte[] key, String str) throws Exception {
// 密码器 加密器
Cipher cipher = Cipher.getInstance("RSA");
// 1: 加密
// getPriKey(key): 使用私钥key获取私钥对象
cipher.init(1, getPriKey(key));
// 加密
byte[] b1 = cipher.doFinal(str.getBytes("utf-8"));
// 字节数组专十六进制字符串
return bytesToHexString(b1);
}
/**
* 获取密钥对
*
* @return 公钥对象+私钥对象
* @throws NoSuchAlgorithmException
*/
public static KeyPair getKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048, new SecureRandom());
// 包含 私钥+公钥
return keyPairGen.generateKeyPair();
}
/**
* 使用秘钥获取私钥对象
*
* @param prikey 秘钥
* @return 秘钥对象
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public static PrivateKey getPriKey(byte[] prikey) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(prikey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
}
/**
* 使用过秘钥获取公钥对象
*
* @param pubkey 秘钥
* @return 秘钥对象
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public static PublicKey getPubKey(byte[] pubkey) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubkey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(x509EncodedKeySpec);
}
/**
* 16进制字符串转byte数组
*
* @param str
* @return
*/
public static byte[] hexStringToBytes(String str) {
if (str == null || str.trim().equals("")) {
return new byte[0];
}
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < str.length() / 2; i++) {
String subStr = str.substring(i * 2, i * 2 + 2);
bytes[i] = (byte) Integer.parseInt(subStr, 16);
}
return bytes;
}
private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
/**
* byte数组转16进制字符串
*
* @param bytes
* @return
*/
public static String bytesToHexString(byte[] bytes) {
char[] buf = new char[bytes.length * 2];
int a = 0;
int index = 0;
for (byte b : bytes) { // 使用除与取余进行转换
if (b < 0) {
a = 256 + b;
} else {
a = b;
}
buf[index++] = HEX_CHAR[a / 16];
buf[index++] = HEX_CHAR[a % 16];
}
return new String(buf);
}
}