这里介绍我们已经有了私钥和公钥(不是java序列化的文件)之后的加密解密。
简要介绍一下如何生成公钥和私钥:
上图中的两个命令:
genrsa -out rsa_private_key.pem 1024
执行之后,当前目录就出现了公钥的文件。
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
注意只需要中间那段看不懂的玩意儿。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import sun.misc.BASE64Decoder;
public class RSATest2 {
public static void main(String[] arg) throws Exception {
String pubKey = “MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC41gBq3rddUovK+uh2TQ0fiLfJXC4/kDncXqXIuy6dnrCiOGqX0gquQsuFAaqolC+iGj3+UXu7Qzi8TS49F1oRBQ3XQUwrwta/t1K0kcHmtGghznyfCMuyBMW6s0MA3H/ZOsiaqt4x6gHIcvpLU/9P4oRdhIxy3Tiycx/dwZi+KwIDAQAB”;
//PKCS8编码的私钥
String priKey = “MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALjWAGret11Si8r66HZNDR+It8lcLj+QOdxepci7Lp2esKI4apfSCq5Cy4UBqqiUL6IaPf5Re7tDOLxNLj0XWhEFDddBTCvC1r+3UrSRwea0aCHOfJ8Iy7IExbqzQwDcf9k6yJqq3jHqAchy+ktT/0/ihF2EjHLdOLJzH93BmL4rAgMBAAECgYEAj8Nzo6wC9wUjUgeCE7GuiV5vhKC8IBhvyKWdUNm2UkaBoEs9LUTjpdKyNYusT16jBfRfT5XVJTwNvvhRBJdLJythtIoWisxxjhZjrwkGSd/1bu7pIeKFspHkVn1ze1poElXruc3NBwwFdSwMHR8U2IXlCjPcTQ+nDpsocI8sKDECQQDabfAZrIiNZZKg5A4M6j/2+oKV4nppNL6oS1O9IGvmnViPTQ9iFnBS3qQPzAxGdggB5f7haXQ7SpF9Jct5t9+9AkEA2KDY9pJYLDCCDY3fA8asAH9qgbbqhMX7lvEQZoLiB/9i6ydA3kGE+kMlvvME3r1nHyMDwvmG6hFpx/0WDKIgBwJAXt8bRvtyP//bBPioxaFE8Q/zgghhZKqdGNnG4EFhvEOhQHSW9uKKHORI2/ejaUNAzRpJbzxvWIVV1caBrzdW/QJBAIdlsXYb7iRghUj3fYacrHD7MpS0wUwPerrTHU8VSzV4eFlGBZNlHDpXscXxmv+lHkkl13oMADlYfOdU1m07AA0CQQCwxcRRSecXt79422jSuBCAvKzGhgAaZqn5/L57Ouo2dGDoxopgEQZLDAbiKwcNW7GNmhG3DOiKo+1fjFy1SHgD”;
Key publicKey = getPubKey(pubKey);
Key privateKey = getPrivateKey(priKey);
encrypt(“D:\se\1.txt”, “D:\se\2.txt”, publicKey);
decrypt(“D:\se\2.txt”, “D:\se\3.txt”, privateKey);
encrypt(“D:\se\1.txt”, “D:\se\4.txt”, privateKey);
decrypt(“D:\se\4.txt”, “D:\se\5.txt”, publicKey);
}
private static PublicKey getPubKey(String pubKey) {
PublicKey publicKey = null;
try {
// 自己的公钥(测试)
X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(
new BASE64Decoder().decodeBuffer(pubKey));
// RSA对称加密算法
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance(“RSA”);
// 取公钥匙对象
publicKey = keyFactory.generatePublic(bobPubKeySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return publicKey;
}
private static PrivateKey getPrivateKey(String priKey) {
PrivateKey privateKey = null;
PKCS8EncodedKeySpec priPKCS8;
try {
priPKCS8 = new PKCS8EncodedKeySpec(
new BASE64Decoder().decodeBuffer(priKey));
KeyFactory keyf = KeyFactory.getInstance(“RSA”);
privateKey = keyf.generatePrivate(priPKCS8);
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return privateKey;
}
/**
* 加密
*
* @param srcPath
* 要加密的源文件的位置
* @param destPath
* 加密后的文件的位置
* @param pkey
* 公钥/或私钥
* @throws Exception
*/
private static void encrypt(String srcPath, String destPath,Key pkey)
throws Exception {
KeyGenerator keygen = KeyGenerator.getInstance(“AES”);
SecureRandom random = new SecureRandom();
keygen.init(random);
SecretKey key = keygen.generateKey();
Cipher cipher = Cipher.getInstance(“RSA”);
cipher.init(Cipher.WRAP_MODE, pkey);
byte[] wrappedKey = cipher.wrap(key);
DataOutputStream out = new DataOutputStream(new FileOutputStream(
destPath));
out.writeInt(wrappedKey.length);
out.write(wrappedKey);
InputStream in = new FileInputStream(srcPath);
cipher = Cipher.getInstance(“AES”);
cipher.init(Cipher.ENCRYPT_MODE, key);
crypt(in, out, cipher);
in.close();
out.close();
}
/**
* 解密
*
* @param srcPath
* 要解密的源文件的位置
* @param destPath
* 解密后的文件的位置
* @param pkey
* 私钥/或公钥
* @throws Exception
*/
private static void decrypt(String srcPath, String destPath,Key pkey)
throws Exception {
DataInputStream in = new DataInputStream(new FileInputStream(srcPath));
int length = in.readInt();
byte[] wrappedKey = new byte[length];
in.read(wrappedKey, 0, length);
Cipher cipher = Cipher.getInstance(“RSA”);
cipher.init(Cipher.UNWRAP_MODE, pkey);
Key key = cipher.unwrap(wrappedKey, “AES”, Cipher.SECRET_KEY);
OutputStream out = new FileOutputStream(destPath);
cipher = Cipher.getInstance(“AES”);
cipher.init(Cipher.DECRYPT_MODE, key);
crypt(in, out, cipher);
in.close();
out.close();
}
private static void crypt(InputStream in, OutputStream out, Cipher cipher)
throws IOException, GeneralSecurityException {
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(blockSize);
byte[] inBytes = new byte[blockSize];
byte[] outBytes = new byte[outputSize];
int inLength = 0;
boolean more = true;
while (more) {
inLength = in.read(inBytes);
if (inLength == blockSize) {
int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
out.write(outBytes, 0, outLength);
} else
more = false;
}
if (inLength > 0)
outBytes = cipher.doFinal(inBytes, 0, inLength);
else
outBytes = cipher.doFinal();
out.write(outBytes);
}
}