import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.apache.commons.codec.binary.Base64;
/**
* @ClassName RSATest
* @Description: 非对称加密的特点是有两把钥匙,公钥和私钥。公钥加密只能私钥解密;私钥加密只能公钥解密。
* 在公开密钥密码*中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。
* 加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
* RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。
* 1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
* 这种加密算法的特点主要是密钥的变化。DES只有一个密钥,相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。
* RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验,确保数据在传输过程中不被修改。
* @Version 1.0
**/
public class RSATest {
// 指定算法
static final String A = "RSA";
static final String B = "SHA256withRSA";
static String publicKey = null;
static String privateKey = null;
public static void main(String[] args) throws Exception {
//Java非对称加密算法--RSA
//非对称加密的特点是有两把钥匙,公钥和私钥。公钥加密只能私钥解密;私钥加密只能公钥解密。
// 生成公钥和私钥
generatorKeyPair();
String source = "admin";
System.out.println("加密前的数据:\r\n" + source);
System.out.println("--------------------------公钥加密,私钥解密------------------------------");
// 公钥加密
String target = encryptionByPublicKey(source);
// 私钥解密
decryptionByPrivateKey(target);
System.out.println("--------------------------私钥加密并且签名,公钥验证签名并且解密------------------------------");
// 私钥加密
target = encryptionByPrivateKey(source);
// 签名
String sign = signByPrivateKey(target);
// 验证签名
verifyByPublicKey(target, sign);
// 公钥解密
decryptionByPublicKey(target);
}
/**
* @MethodName: generatorKeyPair
* @Description: 生成密钥对
*/
static void generatorKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(A);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
byte[] keyBs = rsaPublicKey.getEncoded();
publicKey = encodeBase64(keyBs);
System.out.println("生成的公钥:\r\n" + publicKey);
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
keyBs = rsaPrivateKey.getEncoded();
privateKey = encodeBase64(keyBs);
System.out.println("生成的私钥:\r\n" + privateKey);
}
/**
* @MethodName: getPublicKey
* @Description: 获取公钥
*/
static PublicKey getPublicKey() throws Exception {
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(decodeBase64(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance(A);
return keyFactory.generatePublic(publicKeySpec);
}
/**
* @MethodName: getPrivateKey
* @Description: 获取私钥
*/
static PrivateKey getPrivateKey() throws Exception {
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(decodeBase64(privateKey));
KeyFactory keyFactory = KeyFactory.getInstance(A);
return keyFactory.generatePrivate(privateKeySpec);
}
/**
* @MethodName: encryptionByPublicKey
* @Description: 公钥加密
*/
static String encryptionByPublicKey(String source) throws Exception {
PublicKey publicKey = getPublicKey();
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipher.update(source.getBytes("UTF-8"));
String target = encodeBase64(cipher.doFinal());
System.out.println("公钥加密后的数据:\r\n" + target);
return target;
}
/**
* @MethodName: decryptionByPublicKey
* @Description: 公钥解密
*/
static void decryptionByPublicKey(String target) throws Exception {
PublicKey publicKey = getPublicKey();
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
cipher.update(decodeBase64(target));
String source = new String(cipher.doFinal(), "UTF-8");
System.out.println("公钥解密后的数据:\r\n" + source);
}
/**
* @MethodName: verifyByPublicKey
* @Description: 公钥验证签名
*/
static void verifyByPublicKey(String target, String sign) throws Exception {
PublicKey publicKey = getPublicKey();
Signature signature = Signature.getInstance(B);
signature.initVerify(publicKey);
signature.update(target.getBytes("UTF-8"));
if (signature.verify(decodeBase64(sign))) {
System.out.println("签名正确!");
} else {
System.out.println("签名错误!");
}
}
/**
* @MethodName: encryptionByPrivateKey
* @Description: 私钥加密
*/
static String encryptionByPrivateKey(String source) throws Exception {
PrivateKey privateKey = getPrivateKey();
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
cipher.update(source.getBytes("UTF-8"));
String target = encodeBase64(cipher.doFinal());
System.out.println("私钥加密后的数据:\r\n" + target);
return target;
}
/**
* @MethodName: decryptionByPrivateKey
* @Description: 私钥解密
*/
static void decryptionByPrivateKey(String target) throws Exception {
PrivateKey privateKey = getPrivateKey();
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
cipher.update(decodeBase64(target));
String source = new String(cipher.doFinal(), "UTF-8");
System.out.println("私钥解密后的数据:\r\n" + source);
}
/**
* @MethodName: signByPrivateKey
* @Description: 私钥签名
*/
static String signByPrivateKey(String target) throws Exception {
PrivateKey privateKey = getPrivateKey();
Signature signature = Signature.getInstance(B);
signature.initSign(privateKey);
signature.update(target.getBytes("UTF-8"));
String sign = encodeBase64(signature.sign());
System.out.println("生成的签名:\r\n" + sign);
return sign;
}
/**
* @MethodName: encodeBase64
* @Description: base64编码
*/
static String encodeBase64(byte[] source) throws Exception {
return new String(Base64.encodeBase64(source), "UTF-8");
}
/**
* @MethodName: decodeBase64
* @Description: Base64解码
*/
static byte[] decodeBase64(String target) throws Exception {
return Base64.decodeBase64(target.getBytes("UTF-8"));
}
}