RSA工具類.java
package com.zjp.common.utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;
/**
* RSAUtil工具類
*/
public class RSAUtil {
// RSA key位數
private static final int KEY_SIZE = 512;
// 單次RSA加密操作所允許的最大塊長度,該值與 KEY_SIZE、padding方法有關。
// 1024key->128,2048key->1256,512key->53,11個字節用於保存padding信息。
private static final int BLOCK_SIZE = 53;
private static final int OUTPUT_BLOCK_SIZE = 64;
// private static final int KEY_SIZE = 1024;
// private static final int BLOCK_SIZE = 117;
// private static final int OUTPUT_BLOCK_SIZE = 128;
// private static final int KEY_SIZE = 2048;
// private static final int BLOCK_SIZE = 245;
// private static final int OUTPUT_BLOCK_SIZE = 256;
private static SecureRandom secrand = new SecureRandom();
public static Cipher rsaCipher;
public static String Algorithm = "RSA";// RSA、RSA/ECB/PKCS1Padding
// public static String
// Algorithm="RSA/ECB/PKCS1Padding";//RSA、RSA/ECB/PKCS1Padding
public RSAUtil() throws Exception {
}
/**
* 生成密鑰對
*
* @return KeyPair
* @throws Exception
* @throws NoSuchAlgorithmException
* @throws Exception
*/
public static KeyPair generateRSAKeyPair() {
KeyPair keyPair = null;
try {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(Algorithm);
// 密鑰位數
keyPairGen.initialize(KEY_SIZE);
// 密鑰對
keyPair = keyPairGen.generateKeyPair();
} catch (Exception e) {
e.printStackTrace();
}
return keyPair;
}
/**
* 生成密鑰對
*
* @return KeyPair
* @throws Exception
* @throws NoSuchAlgorithmException
* @throws Exception
*/
public static String[] generateRSAKeyPairStringArray() {
String[] keypair = new String[2];
try {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(Algorithm);
// 密鑰位數
keyPairGen.initialize(KEY_SIZE);
// 密鑰對
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公鑰
PublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私鑰
PrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = getKeyString(publicKey);
System.out.println("Public KEY===>" + publicKeyString);
keypair[0] = publicKeyString;
String privateKeyString = getKeyString(privateKey);
System.out.println("Private KEY===>" + privateKeyString);
keypair[1] = privateKeyString;
} catch (Exception e) {
System.err.println("Exception:" + e.getMessage());
}
return keypair;
}
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = Base64Encoder.decode(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(Algorithm);
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = Base64Encoder.decode(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(Algorithm);
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
public static String getKeyString(Key key) throws Exception {
byte[] keyBytes = key.getEncoded();
String s = Base64Encoder.encode(keyBytes);
return s;
}
/**
* 對content採用RSA 公鑰加密,再使用BASE64加密
*
* @param strPubKey
* 公鑰值
* @param content
* 明文串
* @return cardSecretPwd
* @throws Exception
*/
public static String encodeSecret(String publicKeyString, String content)
throws Exception {
try {
rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
throw e;
}
Key publicKey = getPublicKey(publicKeyString);
try {
// PublicKey pubkey = keys.getPublic();
rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey, secrand);
// System.out.println(rsaCipher.getBlockSize());
// System.out.println(Message.getBytes("utf-8").length);
// byte[] encryptedData =
// rsaCipher.doFinal(Message.getBytes("utf-8"));
byte[] data = content.getBytes("utf-8");
int blocks = data.length / BLOCK_SIZE;
int lastBlockSize = data.length % BLOCK_SIZE;
byte[] encryptedData = new byte[(lastBlockSize == 0 ? blocks
: blocks + 1) * OUTPUT_BLOCK_SIZE];
for (int i = 0; i < blocks; i++) {
// int thisBlockSize = ( i + 1 ) * BLOCK_SIZE > data.length ?
// data.length - i * BLOCK_SIZE : BLOCK_SIZE ;
rsaCipher.doFinal(data, i * BLOCK_SIZE, BLOCK_SIZE,
encryptedData, i * OUTPUT_BLOCK_SIZE);
}
if (lastBlockSize != 0) {
rsaCipher.doFinal(data, blocks * BLOCK_SIZE, lastBlockSize,
encryptedData, blocks * OUTPUT_BLOCK_SIZE);
}
return Base64Encoder.encode(encryptedData);
} catch (InvalidKeyException e) {
e.printStackTrace();
throw new IOException("InvalidKey");
} catch (ShortBufferException e) {
e.printStackTrace();
throw new IOException("ShortBuffer");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new IOException("UnsupportedEncoding");
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
throw new IOException("IllegalBlockSize");
} catch (BadPaddingException e) {
e.printStackTrace();
throw new IOException("BadPadding");
} finally {
}
}
/**
* 對content採用RSA加密,再BASE64加密
*
* @param privateKeyString
* 私鑰值
* @param content
* 明文串
* @return cardSecretPwd
* @throws Exception
*/
public static String encodeSecretByPriKey(String privateKeyString,
String content) throws Exception {
try {
rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
throw e;
}
Key privateKey = getPrivateKey(privateKeyString);
try {
// PublicKey pubkey = keys.getPublic();
rsaCipher.init(Cipher.ENCRYPT_MODE, privateKey, secrand);
// System.out.println(rsaCipher.getBlockSize());
// System.out.println(Message.getBytes("utf-8").length);
// byte[] encryptedData =
// rsaCipher.doFinal(Message.getBytes("utf-8"));
byte[] data = content.getBytes("utf-8");
int blocks = data.length / BLOCK_SIZE;
int lastBlockSize = data.length % BLOCK_SIZE;
byte[] encryptedData = new byte[(lastBlockSize == 0 ? blocks
: blocks + 1) * OUTPUT_BLOCK_SIZE];
for (int i = 0; i < blocks; i++) {
// int thisBlockSize = ( i + 1 ) * BLOCK_SIZE > data.length ?
// data.length - i * BLOCK_SIZE : BLOCK_SIZE ;
rsaCipher.doFinal(data, i * BLOCK_SIZE, BLOCK_SIZE,
encryptedData, i * OUTPUT_BLOCK_SIZE);
}
if (lastBlockSize != 0) {
rsaCipher.doFinal(data, blocks * BLOCK_SIZE, lastBlockSize,
encryptedData, blocks * OUTPUT_BLOCK_SIZE);
}
return Base64Encoder.encode(encryptedData);
} catch (InvalidKeyException e) {
e.printStackTrace();
throw new IOException("InvalidKey");
} catch (ShortBufferException e) {
e.printStackTrace();
throw new IOException("ShortBuffer");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new IOException("UnsupportedEncoding");
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
throw new IOException("IllegalBlockSize");
} catch (BadPaddingException e) {
e.printStackTrace();
throw new IOException("BadPadding");
} finally {
}
}
/**
* BASE64解密,再RSA解密
*
* @param strPriKey
* 私鑰值
* @param content
* 密文串
* @return 用私鑰解密串
* @throws Exception
*/
public static String decodeSecret(String privateKeyString, String content)
throws Exception {
try {
rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
throw e;
}
byte[] decoded = null;
try {
decoded = Base64Encoder.decode(content);
} catch (Exception e1) {
e1.printStackTrace();
}
Key privateKey = getPrivateKey(privateKeyString);
try {
rsaCipher.init(Cipher.DECRYPT_MODE, privateKey, secrand);
int blocks = decoded.length / OUTPUT_BLOCK_SIZE;
ByteArrayOutputStream decodedStream = new ByteArrayOutputStream(
decoded.length);
for (int i = 0; i < blocks; i++) {
decodedStream.write(rsaCipher.doFinal(decoded, i
* OUTPUT_BLOCK_SIZE, OUTPUT_BLOCK_SIZE));
}
return new String(decodedStream.toByteArray(), "UTF-8");
} catch (InvalidKeyException e) {
e.printStackTrace();
throw new IOException("InvalidKey");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new IOException("UnsupportedEncoding");
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
throw new IOException("IllegalBlockSize");
} catch (BadPaddingException e) {
e.printStackTrace();
throw new IOException("BadPadding");
} finally {
}
}
/**
* BASE64解密,再RSA解密
*
* @param strPriKey
* 私鑰值
* @param content
* 密文串
* @return 用私鑰解密串
* @throws Exception
*/
public static String decodeSecretByPubKey(String publicKeyString,
String content) throws Exception {
try {
rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
throw e;
}
byte[] decoded = null;
try {
decoded = Base64Encoder.decode(content);
} catch (Exception e1) {
e1.printStackTrace();
}
Key publicKey = getPublicKey(publicKeyString);
try {
rsaCipher.init(Cipher.DECRYPT_MODE, publicKey, secrand);
int blocks = decoded.length / OUTPUT_BLOCK_SIZE;
ByteArrayOutputStream decodedStream = new ByteArrayOutputStream(
decoded.length);
for (int i = 0; i < blocks; i++) {
decodedStream.write(rsaCipher.doFinal(decoded, i
* OUTPUT_BLOCK_SIZE, OUTPUT_BLOCK_SIZE));
}
return new String(decodedStream.toByteArray(), "UTF-8");
} catch (InvalidKeyException e) {
e.printStackTrace();
throw new IOException("InvalidKey");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new IOException("UnsupportedEncoding");
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
throw new IOException("IllegalBlockSize");
} catch (BadPaddingException e) {
e.printStackTrace();
throw new IOException("BadPadding");
} finally {
}
}
}
測試:
package com.zjp.test.codec;
import java.security.KeyPair;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import org.junit.Test;
import com.zjp.common.utils.RSAUtil;
/**
* 算法測試
*
* @author babylon
* 2016-5-10
*/
public class RSATest {
public static void main(String[] args) throws Exception {
KeyPair kp = RSAUtil.generateRSAKeyPair();
RSAPublicKey pubk = (RSAPublicKey) kp.getPublic();//生成公鑰
RSAPrivateKey prik= (RSAPrivateKey) kp.getPrivate();//生成私鑰
String publicKey = RSAUtil.getKeyString(pubk);
String privateKey = RSAUtil.getKeyString(prik);
System.out.println("生成的公鑰 " + publicKey);
System.out.println("生成的祕鑰 " + privateKey);
String encodeStr = RSAUtil.encodeSecret(publicKey, "你好啊,嘿嘿嘿");
System.out.println("使用公鑰後加密的內容 :" +encodeStr);
String decodeStr = RSAUtil.decodeSecret(privateKey, encodeStr);
System.out.println("解密後的內容:"+decodeStr);
}
}