一、通过对RSA资料的整理获得如下:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.util.Properties;
import javax.crypto.Cipher;
public class RSANewCoder {
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM;
/**
* 算法类型
*/
public static final String ALGORITHM ;
/**
* String to hold name of the encryption padding.
*
*/
public static final String PADDING ;
/**
* String to hold name of the security provider.
* 提供者
*/
public static final String PROVIDER ;
/**
* String to hold the name of the private key file.
* 私钥文件
*/
public static final String PRIVATE_KEY_FILE;
/**
* String to hold name of the public key file.
* 公钥文件
*/
public static final String PUBLIC_KEY_FILE ;
static{
Properties pro=new Properties();
InputStream is=Object.class.getResourceAsStream("/RSA.properties");
try {
pro.load(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//通过java 属性文件获取对应属性
PRIVATE_KEY_FILE=pro.getProperty("PRIVATE_KEY_FILE");
PUBLIC_KEY_FILE=pro.getProperty("PUBLIC_KEY_FILE");
SIGNATURE_ALGORITHM=pro.getProperty("SIGNATURE_ALGORITHM");
ALGORITHM=pro.getProperty("ALGORITHM");
PADDING=pro.getProperty("PADDING");
PROVIDER=pro.getProperty("PROVIDER");
}
/**
* base64加密、byte转String
* @param input
* @return
* @throws Exception
*/
public static String encryptBASE64(byte[]input) throws Exception{
Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method mainMethod= clazz.getMethod("encode", byte[].class);
mainMethod.setAccessible(true);
Object retObj=mainMethod.invoke(null, new Object[]{input});
return (String)retObj;
}
/**
* base64解密、String转成byte
* @param input
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(String input) throws Exception{
Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method mainMethod= clazz.getMethod("decode", String.class);
mainMethod.setAccessible(true);
Object retObj=mainMethod.invoke(null, input);
return (byte[])retObj;
}
/**
* Generate key which contains a pair of private and public key using 1024
* bytes. Store the set of keys in Prvate.key and Public.key files.
* 密钥文件生成
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws FileNotFoundException
*/
public static void generateKey() {
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(
ALGORITHM, PROVIDER);
keyGen.initialize(1024);
final KeyPair key = keyGen.generateKeyPair();
File privateKeyFile = new File(PRIVATE_KEY_FILE);
File publicKeyFile = new File(PUBLIC_KEY_FILE);
// Create files to store public and private key
if (privateKeyFile.getParentFile() != null) {
privateKeyFile.getParentFile().mkdirs();
}
privateKeyFile.createNewFile();
if (publicKeyFile.getParentFile() != null) {
publicKeyFile.getParentFile().mkdirs();
}
publicKeyFile.createNewFile();
// Saving the Public key in a file
ObjectOutputStream publicKeyOS = new ObjectOutputStream(
new FileOutputStream(publicKeyFile));
publicKeyOS.writeObject(key.getPublic());
publicKeyOS.close();
// Saving the Private key in a file
ObjectOutputStream privateKeyOS = new ObjectOutputStream(
new FileOutputStream(privateKeyFile));
privateKeyOS.writeObject(key.getPrivate());
privateKeyOS.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* The method checks if the pair of public and private key has been
* generated.
* 密钥文件判断是否存在
* @return flag indicating if the pair of keys were generated.
*/
public static boolean areKeysPresent() {
File privateKey = new File(PRIVATE_KEY_FILE);
File publicKey = new File(PUBLIC_KEY_FILE);
if (privateKey.exists() && publicKey.exists()) {
return true;
}
return false;
}
/**
* Encrypt the plain text using public key.
* 加密
* @param text
* : original plain text
* @param key
* :The public key
* @return Encrypted text
* @throws java.lang.Exception
*/
public static byte[] encrypt(String text, PrivateKey key) {
byte[] cipherText = null;
try {
// get an RSA cipher object and print the provider
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
final Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
/**
* 用私钥对信息生成数字签名
*
* @param data
* 加密数据
* @param privateKey
* 私钥
*
* @return
* @throws Exception
*/
public static String sign(byte[] data, PrivateKey privateKey) throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateKey);
signature.update(data);
return encryptBASE64(signature.sign());
}
public static boolean verify(byte[] data, PublicKey publicKey, String sign)
throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicKey);
signature.update(data);
// 验证签名是否正常
return signature.verify(decryptBASE64(sign));
}
/**
* Decrypt text using private key.
* 解密
* @param text
* :encrypted text
* @param key
* :The private key
* @return plain text
* @throws java.lang.Exception
*/
public static String decrypt(byte[] text, PublicKey key) {
byte[] dectyptedText = null;
try {
// get an RSA cipher object and print the provider
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
final Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
// decrypt the text using the private key
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
} catch (Exception ex) {
ex.printStackTrace();
}
return new String(dectyptedText);
}
/**
* 通过base64字节转换成字符串
* @param data :encodeOrder-byte
*
* @return encodeOrder-String
*/
public static String byteToStringAndBase64(byte[] data){
try {
return encryptBASE64(data);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static PublicKey getPublicKey(){
ObjectInputStream inputStream = null;
try {
inputStream = new ObjectInputStream(new FileInputStream(
PUBLIC_KEY_FILE));
return (PublicKey)inputStream.readObject();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static PrivateKey getPrivateKey(){
ObjectInputStream inputStream = null;
try {
inputStream = new ObjectInputStream(new FileInputStream(
PRIVATE_KEY_FILE));
return (PrivateKey)inputStream.readObject();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
二、测试
public static void main(String[] args) {
try {
// Check if the pair of keys are present else generate those.
if (!areKeysPresent()) {
// Method generates a pair of keys using the RSA algorithm and
// stores it
// in their respective files
generateKey();
}
final String originalText = "hello world";
ObjectInputStream inputStream = null;
final PublicKey publicKey =getPublicKey();
final PrivateKey privateKey = getPrivateKey();
final byte[] cipherText = encrypt(originalText, privateKey);
String cipherTextBase64 =byteToStringAndBase64(cipherText);
byte[] cipherTextArray = RSACoder.decryptBASE64(cipherTextBase64);
final String plainText = decrypt(cipherTextArray, publicKey);
String sign=sign(cipherText, privateKey);
boolean is=verify(cipherText, publicKey, sign);
// Printing the Original, Encrypted and Decrypted Text
System.out.println("验证签名="+is);
System.out.println("签名="+sign);
System.out.println("加密前=" + originalText);
System.out.println("加密后=" + cipherTextBase64);
System.out.println("解密后=" + plainText);
} catch (Exception e) {
e.printStackTrace();
}
}
注意:加密和解密最好不要放在同一个程序里
属性文件: