概念
何为对称加解密?
- 数据在A加密, B解密, A加密---B解密 是一对一 为对称
何为非对称加解密?
- A加密---B解密; A解签--B加签, 看出来了吗? 有两对, 为非对称
生成秘钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGOGRITHM);
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey pubKey = (RSAPublicKey)keyPair.getPublic();
PrivateKey priKey = (RSAPrivateKey)keyPair.getPrivate();
System.out.println("公钥: "+ new BASE64Encoder().encodeBuffer(pubKey.getEncoded()));
System.out.println("私钥: "+ new BASE64Encoder().encodeBuffer(priKey.getEncoded()));
将秘钥对以文件形式存储;
公钥加密私钥解密
/**
* RSA公钥加密
*/
public static String encrypt( String str, String publicKey ) throws Exception{
//base64解码公钥
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(ALGOGRITHM).generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance(ALGOGRITHM);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
return outStr;
}
/**
* RSA私钥解密
*/
public static String decrypt(String str, String privateKey) throws Exception{
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(ALGOGRITHM).generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance(ALGOGRITHM);
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
主函数
private static final String ALGOGRITHM = "RSA";
private static final String PUBLIC_KEY_PATH = "C:\\Users\\alw\\Desktop\\pub.key";
private static final String PRIVATE_KEY_PATH = "C:\\Users\\alw\\Desktop\\pri.key";
public static String readToString(String fileName) {
String fileContent = "";
FileInputStream fis = null;
File file = new File(fileName);
byte[] by = new byte[Long.valueOf(file.length()).intValue()];
try {
fis = new FileInputStream(file);
fis.read(by);
fileContent = new String(by, "UTF-8");
}catch (Exception e) {
}finally {
try {
fis.close();
} catch (IOException e) {}
}
return fileContent;
}
public static void main(String[] args)throws Exception {
// 明文加密
String message = "hackdream";
String ciphertext = encrypt(message, readToString(PUBLIC_KEY_PATH));
System.out.println("信息密文为:" + ciphertext);
String cleartext = decrypt(ciphertext, readToString(PRIVATE_KEY_PATH));
System.out.println("密文解密后:" + cleartext);
}
私钥签名公钥验签
/**
* 私钥签名
* @param content 报文
* @param privateKey 私钥
* @return 签名值
*/
public static String signByPrivateKey(String content,String privateKey)throws Exception{
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
KeyFactory keyFactory = KeyFactory.getInstance(ALGOGRITHM);
PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance("SHA256withRSA");//MD5withRSA
signature.initSign(priKey);
signature.update(content.getBytes());
byte[] sign = signature.sign();
return Base64.encode(sign);
}
/**
* 公钥验签
* @param content 报文
* @param publicKey 公钥
* @param sign 签名值
* @return 验签是否通过
*/
public static boolean verifySignByPublicKey(String content,String publicKey,String sign)throws Exception{
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance(ALGOGRITHM);
PublicKey pubKey = keyFactory.generatePublic(x509EncodedKeySpec);
Signature signature = Signature.getInstance("SHA256withRSA");//MD5withRSA
signature.initVerify(pubKey);
signature.update(content.getBytes());
return signature.verify(Base64.decode(sign));
}
主函数
private static final String ALGOGRITHM = "RSA";
private static final String PUBLIC_KEY_PATH = "C:\\Users\\alw\\Desktop\\pub.key";
private static final String PRIVATE_KEY_PATH = "C:\\Users\\alw\\Desktop\\pri.key";
public static String readToString(String fileName) {
String fileContent = "";
FileInputStream fis = null;
File file = new File(fileName);
byte[] by = new byte[Long.valueOf(file.length()).intValue()];
try {
fis = new FileInputStream(file);
fis.read(by);
fileContent = new String(by, "UTF-8");
}catch (Exception e) {
}finally {
try {
fis.close();
} catch (IOException e) {}
}
return fileContent;
}
public static void main(String[] args)throws Exception {
// 私钥签名 -> 拿着签名内容与公钥验签的值去对比, 能匹配说明内容在传输途中没被修改
String signFlag = "hackdream";
String sign = signByPrivateKey(signFlag, readToString(PRIVATE_KEY_PATH));
System.out.println("sign:"+sign);
// 公钥验签
System.out.println("验签:"+verifySignByPublicKey(signFlag, readToString(PUBLIC_KEY_PATH), sign));
}