注释写的很详细,直接上代码。
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(); } }