注释写的很详细,直接上代码。
RSA
private static final String PUBLIC_KEY_PATH = "D:/Testkey/public.txt";
private static final String PRIVATE_KEY_PATH = "D:/Testkey/private.txt";
/*
* *生成私钥 公钥
*/
public static void geration(){
KeyPairGenerator keyPairGenerator;
try {
//KeyPairGenerator类用于生成公钥和私钥对。密钥对生成器使用getInstance工厂方法(返回给定类实例的静态方法)构造而成 .
//用于特定算法的密钥对生成器创建可以与该算法一起使用的公钥/私 吧钥对。 它还将算法特定的参数与生成的每个密钥相关联。
//如果算法是DSA算法和密钥大小(模数的大小)为512,768,或1024,那么Sun提供使用为一组预先计算的值的p , q和g参数。
// getInstance(String algorithm) 返回实现指定的随机数生成器(RNG)算法的SecureRandom对象
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
//SecureRandom这个类提供了一个密码强的随机数生成器(RNG)。
SecureRandom secureRandom = new SecureRandom(new Date().toString().getBytes());
/*独立于算法的初始化
所有密钥对生成器共享密钥大小和随机源的概念。 对于不同的算法来说,keyize被不同地解释
(例如,在DSA算法的情况下,keysize对应于模数的长度)。 此KeyPairGenerator类中有一个initialize方法,
它接受这两个普遍共享的参数类型。 还有一个只带有keysize参数,并使用SecureRandom实现的最高优先级安装的提供作为随机源。
(如果没有一个已安装的提供商提供SecureRandom的SecureRandom ,则使用系统提供的随机源。)
由于在调用上述与算法无关的initialize方法时没有指定其他参数,因此提供者如何处理与每个密钥相关联的特定于算法的参数(如果有的话)。
如果算法是DSA算法和密钥大小(模数的大小)为512,768,或1024,那么Sun提供使用为一组预先计算的值的p , q和g参数。
如果模数大小不是上述值之一, Sun提供商将创建一组新的参数。 其他提供商可能预先计算的参数集超过上述三个模数大小。
还有一些可能没有预先计算的参数的列表,而不是总是创建新的参数集。
*/
keyPairGenerator.initialize(1024, secureRandom);
//这个类是密钥对(一个公钥和一个私钥)的简单持有者。
KeyPair keyPair = keyPairGenerator.genKeyPair();
//.getPublic 方法 返回对此密钥对的公钥组件的引用。
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
//PUBLIC_KEY_PATH 公钥路径
FileOutputStream fos = new FileOutputStream(PUBLIC_KEY_PATH);
//写入公钥 .write方法 将指定的字节写入此文件输出流。 实现write方法OutputStream 。
fos.write(publicKeyBytes);
//
fos.close();
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
//PRIVATE_KEY_PATH 私钥路径
fos = new FileOutputStream(PRIVATE_KEY_PATH);
//写入私钥 .write方法 将指定的字节写入此文件输出流。 实现write方法OutputStream 。
fos.write(privateKeyBytes);
fos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取公钥
* @param filename
* @return
* @throws Exception
*/
public static PublicKey getPublicKey(String filename) throws Exception {
File f = new File(filename);
//FileInputStream用于读取诸如图像数据的原始字节流。
//FileInputStream(File file) 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream fis = new FileInputStream(f);
//DataInputStream(InputStream in) 创建使用指定的底层InputStream的DataInputStream。
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int)f.length()];
/*
* 从包含的输入流中读取一些字节数,并将它们存储到缓冲区数组b 。 实际读取的字节数作为整数返回。
* 该方法阻塞直到输入数据可用,检测到文件结束或抛出异常。
如果b为null,则抛出NullPointerException 。 如果b的长度为零,则不会读取字节并返回0 ;
否则,尝试读取至少一个字节。 如果没有字节可用,因为流在文件结尾,则返回值-1 ; 否则,读取至少一个字节并存储到b 。
读取的第一个字节存储在元素b[0] ,下一个字节存入b[1]等等。 读取的字节数最多等于b的长度。
让k是实际读取的字节数; 这些字节将存储在元素b[0]至b[k-1] ,使元素b[k]至b[b.length-1]不受影响。
* */
dis.readFully(keyBytes);
dis.close();
//该类表示公钥的ASN.1编码,根据ASN.1类型SubjectPublicKeyInfo进行编码。
//byte[] 返回按照X.509标准编码的关键字节。
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
//getInstance(String algorithm) 返回一个KeyFactory对象,它转换指定算法的公钥/私钥。
KeyFactory kf = KeyFactory.getInstance("RSA");
//generatePublic(KeySpec keySpec) 从提供的密钥规范(密钥材料)生成公钥对象
return kf.generatePublic(spec);
}
/**
* 获取私钥
* @param filename
* @return
* @throws Exception
*/
public static PrivateKey getPrivateKey(String filename)throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int)f.length()];
dis.readFully(keyBytes);
dis.close();
PKCS8EncodedKeySpec spec =new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
main方法:
public static void main(String[] args) {
//生成公钥密钥
geration();
String input = "我的密码wifi是:12345678";
//RSAPublicKey RSA公钥的接口。
RSAPublicKey pubKey;
//RSAPrivateKey RSA私钥的接口。
RSAPrivateKey privKey;
byte[] cipherText;
//Cipher 该类提供加密和解密的加密密码的功能。 它构成了Java加密扩展(JCE)框架的核心。
Cipher cipher;
try {
// getInstance(String transformation) 返回实现 Cipher对象
cipher = Cipher.getInstance("RSA");
pubKey = (RSAPublicKey) getPublicKey(PUBLIC_KEY_PATH);
privKey = (RSAPrivateKey) getPrivateKey(PRIVATE_KEY_PATH);
//init(int opmode, Certificate certificate) 使用给定证书中的公钥初始化此密码
//ENCRYPT_MODE 常数用于将密码初始化为加密模式。
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
cipherText = cipher.doFinal(input.getBytes());
//加密后的东西
System.out.println("cipher: " + new String(cipherText));
//开始解密
//init(int opmode, Key key) 用密钥初始化此密码。
//DECRYPT_MODE 常数用于将密码初始化为解密模式。
cipher.init(Cipher.DECRYPT_MODE, privKey);
byte[] plainText = cipher.doFinal(cipherText);
//System.out.println("publickey: " + Base64.getEncoder().encode(cipherText));
System.out.println("publickey: " +Base64.encode(cipherText));
System.out.println("plain : " + new String(plainText));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}